c ++套接字编程:sendto()和recvfrom()错误代码10038&在'服务器'绑定失败10038

时间:2014-09-30 21:09:22

标签: c++ sockets udp

//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 receiver\n";

    //Initialize winsock
    if (WSAStartup(MAKEWORD(2,2),&wsaData) != 0)
    {
        cout << "Failed. Error Code : " << WSAGetLastError();
        exit(EXIT_FAILURE);
    }
    cout << "Initialised\n";`

    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 message\n";

        //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 book\n";

    //Initialize socket
    if (WSAStartup(MAKEWORD(2,2),&wsaData) != 0)
    {
        cout << "Failed. Error Code : " << WSAGetLastError();
        exit(EXIT_FAILURE);
    }
    cout << "Initialised\n";

    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 successful\n";

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

1 个答案:

答案 0 :(得分:3)

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

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

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. 在进入bind()循环之前,您的UDP接收方未检查recvfrom()的错误返回值。