C语言应用程序在同一台机器上进行套接字通信

3
我正在使用C语言和Linux平台开发两个小应用程序。第一个是客户端,通过套接字发送字符;第二个是服务器,读取消息并发送回读取到的同样内容。
一旦应用程序之间建立了连接,下面的代码将发送和接收相同的消息5次:
代码已编辑:
char buf[100];
char message[100];
fd_set readfds, writefds;
int n, rvd;

memset(message, 0, sizeof(message));
message[0] = 'a';

inet_ntop(p->ai_family, get_in_addr((struct sockaddr *)p->ai_addr), s, sizeof s);
printf("client: connecting to,, %s\n", s);

freeaddrinfo(servinfo);

n = sockfd+1;

for (unsigned long i=0; i<5; i++)
{

    FD_ZERO(&readfds);
    FD_ZERO(&writefds);

    FD_SET(sockfd, &readfds);
    FD_SET(sockfd, &writefds);

    rvd = select(n, NULL, &writefds, NULL, NULL);

    if (rvd > 0)
    {
        printf("client: writing '%s'\n",message);
        if ((numSent = send(sockfd, message, strlen(message), 0)) != -1)
        {

            rvd = select(n, &readfds, NULL, NULL, NULL);
            if (rvd > 0)
            {
                if ((numbytes = recv(sockfd, buf, numSent, 0)) != -1)
                {
                    printf("client: received '%s'\n",buf);
                }
                //timestamp it
                //count successful package sent
            }
            else
            {
                //throw this measurement
            }
        }
    }
}

该程序成功发送和接收消息两次。当尝试第三次发送时失败,即使函数select返回一个大于0的值(这意味着服务器已准备好接收数据)。
在使用eclipse进行调试时,函数send()在第三次执行时崩溃,并显示以下消息: 无法获取“send() at 0x7ffff7bcc282”的源代码 查看反汇编... [按钮]
然而,在虚拟机上运行服务器应用程序一切正常。
有什么想法吗?提前感谢!

2
每次发送后返回了什么?您是否在每个函数之后检查返回代码和errno?请打印它们。 - Vality
重要的是显示 messagebuf 的定义,以及如何填充 message - chux - Reinstate Monica
2
你的代码片段太短了。不清楚 writefdsreadfds 是否只包含 sockfd,如果是这样,你可以直接使用阻塞套接字进行 sendrecv,因为你无论如何都使用了 select 而没有设置超时。此外,你没有展示是否正确设置了 n。你用 %s 打印 message,但声称它是一个 char,所以应该使用 %c。由于你似乎对 printf 没有问题,我假设 message 是一个 char*const char*,这会导致在写入 buf 时出现问题,而使用 sizeof(message) 而不是你的 buf 变量的大小。 - foobar
sizeof(message) 不等于 size_t len 的值。最好使用 send(sockfd, message, strlen(message), 0) 来发送 message 中字符的数量,而不是使用 sizeof(char *) - David C. Rankin
@DenisDantas: sizeof(char*) != strlen(char*). 你需要停止使用sizeof(),因为你没有正确使用它。 - Remy Lebeau
显示剩余2条评论
1个回答

1

你的代码存在两个问题:

  1. 每次调用 select() 时,你没有重置 readfdswritefds,因为它们会在每次调用中被修改。

  2. 你误用了 sizeof()

尝试使用以下代码:

char message[1024];
char buf[1024];
fd_set readfds, writefds;
int numSent, numRead;

memset(message, 0, sizeof(message));
strncpy(message, "whatever you need to send...", sizeof(message)-1);

for (unsigned long i = 0; i < 5; ++i)
{
    FD_ZERO(&writefds);
    FD_SET(sockfd, &writefds);

    FD_ZERO(&readfds);
    FD_SET(sockfd, &readfds);

    rvd = select(sockfd+1, NULL, &writefds, NULL, NULL); 
    if (rvd == -1)
        break;

    printf("client: writing '%s'\n", message);
    if ((numSent = send(sockfd, message, strlen(message), 0)) < 1)
        break;

    rvd = select(sockfd+1, &readfds, NULL, NULL, NULL);
    if (rvd == -1)
        break;

    if ((numRead = recv(sockfd, buf, numSent, 0)) < 1)
        break;

    printf("client: received '%*s'\n", numRead, buf);
}

我现在已经将FD_ZERO和FD_SET包含在for循环中,以便重置readfds和writefds,并且我还使用strlen + numSet来指定要发送和接收的数据长度。但是程序仍然在send()上出现问题,并且在调试模式下eclipse显示相同的消息。 - Denis Dantas
请更新您的问题,包括所有相关声明,特别是 messagebuf,并附上最新代码。 - Remy Lebeau
我刚刚做了那件事。如果还有什么不清楚的,请告诉我。 - Denis Dantas

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接