Reputation: 3
My code is behaving very strange on Windows, but working on Linux... This is my server.cpp:
#include <cstdio>
#include "packet.h"
#include "socket.h"
int main(int argc, char *argv[])
{
Socket s;
s.bindAt(1337);
for (int i = 0; i < 20; i++) {
Packet p;
int32_t a;
char *b;
int abc = s.receive();
printf("abc = %d\n", abc);
printf("error = %d\n", WSAGetLastError());
p.getInt(&a);
p.getString(&b);
printf("int = %d\nstring = %s\n", a, b);
delete[] b;
}
return 0;
}
and here is the socket.cpp:
Socket::Socket()
{
#ifdef _WIN32
WSADATA wsa;
if (sockNum == 0 && WSAStartup(MAKEWORD(2, 2), &wsa) != 0)
throw 1;
#endif
sock = socket(AF_INET, SOCK_DGRAM, 0);
#ifdef _WIN32
if (sock == INVALID_SOCKET)
#else
if (sock == -1)
#endif
throw 2;
addrlen = 0;
sockNum++;
}
int Socket::bindAt(unsigned short port)
{
struct sockaddr_in sa = { 0 };
memset(&sa, 0, sizeof(sa));
sa.sin_family = AF_INET;
sa.sin_port = htons(port);
sa.sin_addr.s_addr = htonl(INADDR_ANY);
return bind(sock, (struct sockaddr *) &sa, sizeof(sa));
}
ssize_t Socket::receive()
{
ssize_t n;
#ifdef _WIN32
char msg[100];
n = recvfrom(sock,msg, sizeof(msg), 0,(SOCKADDR*) &addr, &addrlen);
#else
n = recvfrom(sock, p->buf, p->bufSize, 0,
(struct sockaddr *) &addr, &addrlen);
#endif
/*if (n < 0)
p->bufSize = 0;
else
p->bufSize = n;*/
return n;
}
and basically the header of it:
typedef SOCKET socket_t;
typedef int ssize_t;
class Socket
{
public:
socket_t sock;
socklen_t addrlen;
struct sockaddr_in addr;
Socket();
~Socket();
int connect(const char *ip, unsigned short port);
int bindAt(unsigned short port);
ssize_t send(Packet *p);
ssize_t receive();
};
If I change the last 2 parameters of the recvfrom, the (SOCKADDR*) &addr, and &addrlen to NULL it works, but what is wrong with these 2 parameters?
Upvotes: 0
Views: 2805
Reputation: 7447
instead of this :
addrlen = 0;
do this:
addrlen = sizeof(sockaddr_in)
it should work, because you are identifying correctly the size of the output address buffer pointer.
Upvotes: 4
Reputation: 780663
From MSDN description of WSAEFAULT
(10014):
The system detected an invalid pointer address in attempting to use a pointer argument of a call. This error occurs if an application passes an invalid pointer value, or if the length of the buffer is too small. For instance, if the length of an argument, which is a sockaddr structure, is smaller than the sizeof(sockaddr).
So if you supply an uninitialized value of addrlen
, it may be too small, and result in this error.
If addr
is NULL
, it means you don't want the address filled in, so addrlen
is ignored.
Upvotes: 2