c - 使用winsock接收UDP数据包

标签 c sockets udp winsock

我不断从端口接收 UDP 数据包。以下是来自 wireshark 的日志。 如何使用 winsock 编程连续接收这些数据包。我试过了,但我无法接收。 recvfrom() 调用后,它不会写入缓冲区。请告诉我如何在缓冲区中接收每个数据包并将每个数据包写入文本文件。请帮我。提前致谢...

源 IP 是 192.168.13.25 & 端口号是 2780(源是一个硬件,它会连续发送 UDP 数据包) 目标 IP 是 192.168.13.250 & 端口号是 45141(目标是我的电脑) 在我的代码中,我绑定(bind)到 192.168.13.250(PC) 和端口 2780(硬件)。然后我调用 recvfrom()。是不是IP和端口不匹配?? 那么对于 bind() 和 recvfrom() 我需要从用户那里获取哪个 IP 和端口号?

No  Time        Source          Destination     Proto  Info                                                                       
1   0.000000    192.168.13.25   192.168.13.250  UDP    Source port: lbc-control  Destination port: 45141
2   0.000416    192.168.13.25   192.168.13.250  UDP    Source port: lbc-control  Destination port: 45141
3   0.000846    192.168.13.25   192.168.13.250  UDP    Source port: lbc-control  Destination port: 45141
4   0.001281    192.168.13.25   192.168.13.250  UDP    Source port: lbc-control  Destination port: 45141
5   0.001716    192.168.13.25   192.168.13.250  UDP    Source port: lbc-control  Destination port: 45141
6   0.002152    192.168.13.25   192.168.13.250  UDP    Source port: lbc-control  Destination port: 45141
7   0.002589    192.168.13.25   192.168.13.250  UDP    Source port: lbc-control  Destination port: 45141
8   0.003025    192.168.13.25   192.168.13.250  UDP    Source port: lbc-control  Destination port: 45141

Following is my code:

int main(void) {
    SOCKET recvSockID;
    WSADATA wsaData = {0};
    FILE *udp;
    FILE *fp ;

    struct sockaddr_in sock_addr;
    struct sockaddr_in cliAddr;

    static int recvData;
    int iResult = 0;
    int sock_len = sizeof(sock_addr);
    int sockCli_len = sizeof(cliAddr);
    int recvResult;
    static int iteration;

    fp = fopen("outOfSeq.txt","a");

    if((udp = fopen("udpData.txt","w")) == 0)
        printf("udpData.txt not opened\n");

    printf("\n Enter Destination IP Address : ");
    scanf_s("%s",inputData.destIPAddr,16);

    printf("\n Enter Destination port from which to receive data : "); 
    scanf_s("%d",&inputData.portNo,5);

    printf("\n Enter No.of iterations : "); 
    scanf_s("%d",&inputData.noIteration,2);

    iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
    if(iResult < 0) {
        printf("windows socket startup error\n");
    } 

    recvSockID = socket(AF_INET, SOCK_DGRAM, 0);
    if(recvSockID < 0) {
        printf("Socket creation error\n");
        WSACleanup();
    }

    sock_addr.sin_family = AF_INET;
    sock_addr.sin_port = htons(inputData.portNo);
    sock_addr.sin_addr.s_addr = inet_addr(inputData.destIPAddr);
    //sock_addr.sin_addr.s_addr = htonl(INADDR_ANY);

    if(bind(recvSockID, (struct sockaddr *)&sock_addr,
        sizeof(struct sockaddr)) < 0)
    {
        printf("bind() failed: %ld.\n", WSAGetLastError());
        closesocket(recvSockID);
        return 0;
    }

    memset(udpBuf, 0, sizeof(udpBuf));

    iteration = inputData.noIteration;
    recvData = 1;

    while (recvData) {
        printf("receiving data\n");
        recvResult =  recvfrom(recvSockID, udpBuf, sizeof(udpBuf),
            0, (struct sockaddr *)&cliAddr, &sockCli_len); 

        if (recvResult <= 0) {
            printf("recvResult = %d\n", recvResult);

            printf("Error Code: %d",WSAGetLastError());

            printf("Socket receive()- error\n");
            return 0;
            //break;
            //goto exit;
        } else
            printf("Socket receive()- success\n");

        printf("completed rx data\n");

        fwrite(udpBuf, sizeof(udpBuf), 1, udp);
        memset(udpBuf, 0, sizeof(udpBuf));

        if (iteration != 0) {
            iteration--;
            if (iteration <= 0)
                recvData = 0;
        }
    }

//exit:
    if(udp) {
        fclose(udp);
        udp = 0; 
    }

    //shutdown socket
    closesocket(recvSockID);    
    fclose(udp);

    return 0;
}

最佳答案

  1. fwrite(udpBuf, sizeof(udpBuf), 1, udp)

    您应该传递 recvResult 而不是 sizeof(udpBuf)

  2. 由于文件缓冲,您可能不会立即看到文件中的字节。但是,在 close 之后,您应该会看到数据。

    如果您想禁用缓冲,请使用 setvbuf(udp, NULL, _IONBF, 0),或者作为替代方案,在每次写入操作后调用 fflush(udp)

更新:

如果您根本没有收到数据报,很可能是您绑定(bind)了错误的地址或端口。

关于c - 使用winsock接收UDP数据包,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3933166/

相关文章:

c - 声音播放器无法读取我的程序生成的 WAV 文件,提示缺少 header

C++:使用选择()

sockets - iSeries机器上PASE上的网络错误

java - 如何检查用户意外终止连接

c - 在c中使用windows套接字应用程序绑定(bind)错误10038

c - 在输入上动态分配二维数组

c - 我用PolarSSL AES-CBC加密字符串后无法解密

java - doInBackground 卡住了

c++ - 在 C++ 中查看 UDP 消息

java - UDP 收到数据包但打印出有趣的结果