简体   繁体   English

C套接字编程:客户端send()但服务器select()看不到它

[英]C socket programming: client send() but server select() doesn't see it

I have a server and a client running on two different machines where the client send() s but the server doesn't seem to receive the message. 我有一个服务器和一个客户端在两台不同的计算机上运行,​​其中客户端send()但是服务器似乎没有收到消息。 The server employs select() to monitor sockets for any incoming connections/messages. 服务器使用select()监视套接字是否有任何传入的连接/消息。 I can see that when the server accepts a new connection, it updates the fd_set array but always returns 0 despite the client send() messages. 我可以看到,当服务器接受新连接时,它会更新fd_set数组,但无论客户端是否send()消息,它始终返回0。 The connection is TCP and the machines are separated by like one router so dropping packets are highly unlikely. 连接是TCP,并且机器像一台路由器一样被分隔开,因此丢弃数据包的可能性很小。

I have a feeling that it's not select() but perhaps send() / sendto() from client that may be the problem but I'm not sure how to go about localizing the problem area. 我有一种感觉,这可能不是问题,不是select()而是客户端的send() / sendto() ,但是我不确定如何定位问题区域。

    while(1)
{
    readset = info->read_set;   
    ready = select(info->max_fd+1, &readset, NULL, NULL, &timeout);

} }

above is the server side code where the server has a thread that runs select() indefinitely. 上面是服务器端代码,其中服务器具有一个无限期运行select()的线程。

rv = connect(sockfd, (struct sockaddr *) &server_address, sizeof(server_address));
printf("rv = %i\n", rv);
if (rv < 0)
{
    printf("MAIN: ERROR connect() %i:  %s\n", errno, strerror(errno));
    exit(1);
}
else
    printf("connected\n");

sleep(3);

char * somemsg = "is this working yet?\0";
rv = send(sockfd, somemsg, sizeof(somemsg), NULL);
if (rv < 0)
    printf("MAIN: ERROR send() %i:  %s\n", errno, strerror(errno));
printf("MAIN: rv is %i\n", rv);
rv = sendto(sockfd, somemsg, sizeof(somemsg), NULL, &server_address, sizeof(server_address));
if (rv < 0)
    printf("MAIN: ERROR sendto() %i:  %s\n", errno, strerror(errno));
printf("MAIN: rv is %i\n", rv);

and this is the client side where it connects and sends messages and returns 这是客户端连接,发送消息并返回的客户端

connected
MAIN: rv is 4
MAIN: rv is 4

connected 连接的
MAIN: rv is 4 主要:rv为4
MAIN: rv is 4 主要:rv为4

Odd that "rv is 4", especially considering the message was 22 chars long. 奇怪的是,“ rv is 4”,特别是考虑到该消息的长度为22个字符。 "4" also tends to be the size of pointers in most 32 bit environments. 在大多数32位环境中,“ 4”也往往是指针的大小。 You should take a look at what sizeof(somemsg) gives you; 您应该看看sizeof(somemsg)给了您什么; my guess is that it is giving you the size of the pointer (4), not of the string (22). 我的猜测是它为您提供了指针(4)的大小,而不是字符串(22)的大小。

Where are you updating the read set? 您在哪里更新阅读集? The implementation details of the fd_set structure/type aren't part of the BSD sockets interface, as far as I know. 据我所知, fd_set结构/类型的实现细节不是BSD套接字接口的一部分。 It could be a pointer to somewhere, for all you know, and the system could be removing your client's socket from the original set the first time it wasn't "ready", and never checking it again. 众所周知,它可能是指向某个地方的指针,并且系统可能会在第一次未准备好时就从原始集中删除客户端的套接字,而从不对其进行检查。 The only way of updating a fd_set safely and portably is to to use the FD_* macros. 安全且可移植地更新fd_set的唯一方法是使用FD_*宏。

By the way, you don't need the trailing \\0 at the end of the string. 顺便说一句,您不需要在字符串末尾添加\\0 C adds that to string literals for you. C为您将其添加到字符串文字中。

There was something wrong with fd_set readset , rather than what I had thought was problematic. fd_set readset出了点问题,而不是我认为的问题。 PROPS to qrdl for bringing it to my attention. 对qrdl的支持引起了我的注意。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM