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?
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.
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.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.