C windows 套接字在第一次执行时永远被阻塞

标签 c windows sockets winsock

我正在编写一个 C 软件,通过 UDP 与电机 Controller 连接。 我正在使用:

  • Win 7 专业版 64 位
  • eclipse
  • minGW

目前我遇到了一个问题,这似乎与套接字/wsa 相关: 我的程序的执行永远卡在recvfrom()上(所以显然 Controller 没有按预期响应)。 对于附带的软件,这只发生在第一次执行时(或大约 3 分钟未执行后),其他程序连续 3-4 次出现此问题。 对wireshark的研究显示,第一个(或3分钟暂停后)导致传输“ARP”包而不是我的UDP消息。 这是为什么(好像是在寻找目的地)?如何避免我的软件因此而“崩溃”?

我是否忘记初始化任何东西?

我的代码如下所示:

#include <stdio.h>
#include <conio.h>
#include <winsock2.h>

#define Y_AXIS_IP "XXX.XXX.XXX.XX"
#define Y_AXIS_PORT 880X

int startWinsock(void);

int main() {
//Start the winsocket (needed to create sockets)
long ws = startWinsock();
if (ws) {
    printf("ERROR: Failed to init Winsock API! Code: %ld\n", ws);
    getch();
    exit(EXIT_FAILURE);
}
//Create an UDP Socket
SOCKET UDPsocket = socket(AF_INET, SOCK_DGRAM, 0);
if (UDPsocket == INVALID_SOCKET) {
    printf("ERROR: Socket could not be created! Code: %d\n",
            WSAGetLastError());
    getch();
    exit(EXIT_FAILURE);
}
//Create a struct to use with the socket (this gives information about type (AF_INET = Internet Protocol) which port and which IP to use)
SOCKADDR_IN addrY;
memset(&addrY, 0, sizeof(addrY));
addrY.sin_family = AF_INET; //Assert Type
addrY.sin_port = htons(Y_AXIS_PORT);    //Assert Port
addrY.sin_addr.S_un.S_addr = inet_addr(Y_AXIS_IP);  //assert IP Address

char message[] = "0000MTX     00000000OR:1:000F\r";

int buffersize = 100;
char *recvbuf = malloc(buffersize); //None of the replys can get larger than 100 chars

if (recvbuf == NULL) {
    printf("Out of memory!\n");
    getch();
    exit(EXIT_FAILURE);
}

//clear the receive buffer and prepare the address size
memset(recvbuf, '\0', buffersize);
int addrsize = sizeof(addrY);

//Send the message to the device
if (sendto(UDPsocket, message, strlen(message), 0,
        (struct sockaddr *) &addrY, sizeof(addrY)) == SOCKET_ERROR) {
    printf("sendto() failed with error code : %d", WSAGetLastError());
    getch();
    exit(EXIT_FAILURE);
}

//Receive from device (blocks program until recv event)
if (recvfrom(UDPsocket, recvbuf, buffersize, 0, (struct sockaddr *) &addrY,
        &addrsize) == SOCKET_ERROR) {
    //If not timed out Display the Error
    printf("recvfrom() failed with error code : %d", WSAGetLastError());
    getch();
    exit(EXIT_FAILURE);
}

printf("%s\n", recvbuf);
getch();

free(recvbuf);

return 0;
}

int startWinsock(void) {
WSADATA wsa;
return WSAStartup(MAKEWORD(2, 2), &wsa);
}

如果您有任何想法或建议,我会非常高兴。非常感谢!

最佳答案

  • 计算机在向另一台主机发送数据包之前,必须解析其 MAC 地址。这是通过 ARP 请求完成的。它由操作系统透明地处理。

  • recvfrom 将阻塞。这不是一个错误。当没有传入数据时,基本上有三种方法可以避免 recvfrom 永远阻塞:

    1. 使套接字异步,即非阻塞
    2. 设置超时(请参阅 Set timeout for winsock recvfrom)
    3. 使用选择 ( Setting winsock select timeout accurately )

关于C windows 套接字在第一次执行时永远被阻塞,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28504275/

相关文章:

c - 如何使队列线程安全

c - 没有宏扩展的延迟字符串化

java - 拦截发送到 Windows 打印机的数据(使用 RedMon)

javascript - 如何使用JS检测网络中的服务器?

c - GMP pow 中的溢出处理

c - 了解管道

windows - 使用 Windows 任务计划程序启动时 Doxygen 未运行

c# - UPX最好的压缩方式是什么

java - 在android中使用套接字时出现异常错误

c - C中的结构类型转换