C++套接字编程:sendto()和recvfrom()错误代码10038和in 'server'绑定失败,10038

c++ socket programming : sendto() and recvfrom() error code 10038 & in 'server' bind failed with 10038

本文关键字:10038 失败 绑定 server 错误代码 编程 套接字 sendto C++ recvfrom in      更新时间:2023-10-16
//UDP receiver
int main()
{
    WSAData wsaData;
    SOCKET receivingSocket;
    SOCKADDR_IN receiverAddr;
    SOCKADDR_IN senderAddr;
    int senderAddrSize = sizeof(senderAddr);
    int port=51020;
    char receiveBuf[1024];
    int bufLength=1024;
    cout << "UDP receivern";
    //Initialize winsock
    if (WSAStartup(MAKEWORD(2,2),&wsaData) != 0)
    {
        cout << "Failed. Error Code : " << WSAGetLastError();
        exit(EXIT_FAILURE);
    }
    cout << "Initialisedn";`
    if(receivingSocket = socket(AF_INET, SOCK_DGRAM, 0 ) == INVALID_SOCKET )
    {
        cout << "Could not create socket :" << WSAGetLastError();
    }
    cout << "Socket created.n";
    //fill up SOCKADDR_IN structure
    senderAddr.sin_port = htons(port);
    senderAddr.sin_family = AF_INET;
    senderAddr.sin_addr.s_addr = htonl(INADDR_ANY);
    //Bind information with socket
    bind(receivingSocket, (SOCKADDR*)&senderAddr, sizeof(senderAddr));
    while(1)
    {
        cout << "Waiting for messagen";
        //try to receive some data, this is a blocking call
        if (recvfrom(receivingSocket, receiveBuf, 1024, 0, (SOCKADDR*)&senderAddr, &senderAddrSize)) == SOCKET_ERROR))
        {
            cout << "recvfrom() failed with error code :" << WSAGetLastError();
            exit(EXIT_FAILURE);
        }
        cout << receiveBuf;
    }
    //Close socket
    closesocket(receivingSocket);
    WSACleanup();
    std::cin.get();
    return 0;
}

//UDP server
int main()
{
    WSAData wsaData;
    SOCKET sendingSocket;
    SOCKADDR_IN receiverAddr;
    int port = 51010;
    char sendBuf[1024]="Hello!!!";
    int bufLength = 1024;
    cout << "UDP server from bookn";
    //Initialize socket
    if (WSAStartup(MAKEWORD(2,2),&wsaData) != 0)
    {
        cout << "Failed. Error Code : " << WSAGetLastError();
        exit(EXIT_FAILURE);
    }
    cout << "Initialisedn";
    if(sendingSocket = socket(AF_INET, SOCK_DGRAM, 0) == INVALID_SOCKET)
    {
        cout << "Could not create socket : " << WSAGetLastError();
    }
    cout << "Socket created.n";
    //FIll out structure of receiverAdd
    receiverAddr.sin_family = AF_INET;
    receiverAddr.sin_port = htons(port);
    receiverAddr.sin_addr.s_addr = inet_addr("192.168.1.100");
    int test = bind(sendingSocket, (SOCKADDR*)&receiverAddr, sizeof(receiverAddr));
    if( test < 0)
    {
        cout << "Bind failed with error code : %d" << WSAGetLastError();
        exit(EXIT_FAILURE);
    }
    cout << "Bind is successfuln";
    while(1)
    {
        cout << "Sending data...n";
        //Send datagram to receiver
        if(sendto(sendingSocket, sendBuf, 1024, 0, (SOCKADDR*)&receiverAddr, sizeof(receiverAddr)) == SOCKET_ERROR)
        {
            cout << "sendto() failed with error code : " << WSAGetLastError();
            exit(EXIT_FAILURE);
        }
        cout << "Sent";
    }
    //close socket
    closesocket(sendingSocket);
    WSACleanup();
    std::cin.get();
   // return 0;
}

错误 10038 WSAENOTSOCK: The descriptor is not a socket.

您正在调用socket()并在语句if内分配SOCKET句柄,但缺少足够的括号。 它们应该是这样的:

if( (receivingSocket = socket(AF_INET, SOCK_DGRAM, 0)) == INVALID_SOCKET )

if( (sendingSocket = socket(AF_INET, SOCK_DGRAM, 0)) == INVALID_SOCKET )

就个人而言,我讨厌在这样的语句中执行赋值的代码if。 我宁愿把它们分开。 从编译器的角度来看,它更干净,更不容易出错,效率也不低:

receivingSocket = socket(AF_INET, SOCK_DGRAM, 0);
if( receivingSocket == INVALID_SOCKET )

sendingSocket = socket(AF_INET, SOCK_DGRAM, 0);
if( sendingSocket == INVALID_SOCKET )

附带说明一下:

  1. WSAStartup()不使用WSAGetLastError()进行错误报告,而是直接返回错误代码。 这在WSAStartup()文档中有明确说明。

    int err = WSAStartup(MAKEWORD(2,2),&wsaData);
    if (err != 0)
    {
        cout << "Failed. Error Code : " << err;
        exit(EXIT_FAILURE);
    }
    
  2. 在进入recvfrom()循环之前,UDP 接收器未检查 bind() 的返回值是否存在错误。