WinSock未发送就能接收到??

代码运行的结果是不断循环打印2.0.0.0 :recvThread,有一点很不解,在接收线程recvThread的while循环第一句便是recvfrom(),按道理来说应该要等接收成功才会执行,但是在单单只运行这个程序的时候也会出现循环,并且在调试中发现recvfrom从0.0.0.0成功接收了,请问这是什么原因?

#pragma comment (lib, "Ws2_32.lib")
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <WinSock2.h>
#include <tchar.h>
#include <Windows.h>
#include <process.h>

DWORD WINAPI broadcastThread(LPVOID p)
{
    SOCKET localSocket = *(SOCKET*)p;
    const int LOCAL_PORT = 6000;
    int localAddressLength;
    SOCKADDR_IN localAddress;
    localAddress.sin_addr.S_un.S_addr = htonl(INADDR_ANY);//本机地址
    localAddress.sin_family = AF_INET;
    localAddress.sin_port = htons(LOCAL_PORT);
    bind(localSocket, (SOCKADDR*)&localAddress, sizeof(SOCKADDR));//指明本机地址、端口

    //设置广播地址、端口
    const int BROADCAST_PORT = 6001;
    SOCKADDR_IN broadcastAddress;
    int broadcasrAddressLength = sizeof(SOCKADDR);
    broadcastAddress.sin_addr.S_un.S_addr = htonl(INADDR_BROADCAST);//广播地址
    broadcastAddress.sin_family = AF_INET;
    broadcastAddress.sin_port = htons(BROADCAST_PORT);

    int recvAddressLength;
    const int BUF_LENGTH = 512;
    char Buf[BUF_LENGTH] = "recvThread";
    char sendBuf[BUF_LENGTH];
    SOCKADDR_IN recvAddress;
    //发送广播
    while (1)
    {
        recvfrom(localSocket, Buf, BUF_LENGTH, 0, (SOCKADDR*)&recvAddress, &recvAddressLength);
        if (strcmp(inet_ntoa(recvAddress.sin_addr), "220.167.42.115") == 0)
        {
            continue;
        }
        strcpy(sendBuf, inet_ntoa(recvAddress.sin_addr));
        strcat(sendBuf, " : ");
        strcat(sendBuf, Buf);
        printf("%s\n", sendBuf);
        sendto(localSocket, Buf, BUF_LENGTH, 0, (SOCKADDR*)&broadcastAddress, sizeof(SOCKADDR));
    }

    return 0;
}

DWORD WINAPI sendThread(LPVOID p)
{
    //设置广播地址、端口
    const int BROADCAST_PORT = 6001;
    SOCKET localSocket = *(SOCKET*)p;
    SOCKADDR_IN broadcastAddress;
    int broadcasrAddressLength = sizeof(SOCKADDR);
    broadcastAddress.sin_addr.S_un.S_addr = htonl(INADDR_BROADCAST);//广播地址
    broadcastAddress.sin_family = AF_INET;
    broadcastAddress.sin_port = htons(BROADCAST_PORT);

    const int BUF_LENGTH = 512;
    char Buf[BUF_LENGTH] = "sendThread";
    char sendBuf[BUF_LENGTH];
    while (1)
    {
        gets(Buf);
        strcpy(sendBuf, "System: ");
        strcat(sendBuf, Buf);
        printf("%s", sendBuf);
        sendto(localSocket, sendBuf, BUF_LENGTH, 0, (SOCKADDR*)&broadcastAddress, sizeof(SOCKADDR));
    }

    return 0;
}

int _tmain()
{
    int err;
    WORD wVersionRequested;
    WSADATA wsaData;
    wVersionRequested = MAKEWORD(2,2);
    err = WSAStartup(wVersionRequested, &wsaData);
    if (err)
    {
        printf("Initialize WinSock failed, error code: %d\n");
        return 1;
    }

    //绑定本机地址、端口, 监听用
    SOCKET localSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);//套接字
    int broadcastSwitch = TRUE;
    setsockopt(localSocket, SOL_SOCKET, SO_BROADCAST, (char*)&broadcastSwitch, sizeof(broadcastSwitch));
    printf("Waiting...\n");
    
    const int THREAD_NUMBER = 2;
    HANDLE handle[THREAD_NUMBER];
    handle[0] = CreateThread(NULL, 0, broadcastThread, &localSocket, 0, NULL);
    handle[1] = CreateThread(NULL, 0, sendThread, &localSocket, 0, NULL);
    WaitForMultipleObjects(THREAD_NUMBER, handle, TRUE, INFINITE);

    closesocket(localSocket);
    WSACleanup();
    return 0;
}
阅读 3k
1 个回答

问题解决了,原因是代码广播线程broadcastThread中“int recvAddressLength;”没有进行赋值
recvfrom()会根据传入的recvAddressLength对“SOCKADDR_IN recvAddress;”进行初始化,如果recvAddressLength小了就会出错。
而且不知道出错的原因是没有对recvfrom返回值进行查看,导致误以为程序一直运行正常。


解决方法:将int recvAddressLength;改为int recvAddressLength = sizeof(SOCKADDR);


参考:http://blog.csdn.net/u0114782...

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进