簡體   English   中英

C ++ UDP recvfrom行為異常,WSAGetLastError = 10014

[英]C++ UDP recvfrom is acting strange, WSAGetLastError = 10014

我的代碼在Windows上表現很奇怪,但是在Linux上卻可以工作。這是我的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;
}

這是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;
}

基本上是它的標題:

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();
};

如果我將recvfrom的最后兩個參數,(SOCKADDR *)&addr和&addrlen更改為NULL,那么它可以工作,但是這兩個參數有什么問題呢?

代替這個:

addrlen = 0;

做這個:

addrlen = sizeof(sockaddr_in)

它應該起作用,因為您可以正確識別輸出地址緩沖區指針的大小。

WSAEFAULT (10014)的MSDN描述:

系統在嘗試使用調用的指針參數時檢測到無效的指針地址。 如果應用程序傳遞了無效的指針值,或者緩沖區長度太小 ,則會發生此錯誤。 例如,如果參數的長度(是sockaddr結構)小於sizeof(sockaddr)。

因此,如果提供未初始化的addrlen值,則該值可能太小,從而導致此錯誤。

如果addrNULL ,則意味着您不希望填寫該地址,因此addrlen被忽略。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM