c - 无法接收使用 MSG_MORE 标志发送的最后一个套接字数据

标签 c sockets tcp

服务器端代码:

 dirp=opendir(path);
    if(dirp==NULL)
    {
        strcpy(err,"error:");
        strcat(err,strerror(errno));
        send(fd,err,sizeof(err),0); 
    }       
    else
    {
        printf("\nstream opened\n");
        while((dp=readdir(dirp))!= NULL)
        {

            r=send(fd,dp->d_name,100,MSG_MORE);
            if(r<0)
                perror("\nsend:");
            printf("\n%s",dp->d_name);

        }
    }

客户:

while(recv(mainsocket,lsbuf,100,0)>0)
{
    printf("\n %s",lsbuf);
    bzero(lsbuf,sizeof(lsbuf)); 
}

服务器端在标准输出上打印所有文件名,但在客户端,客户端没有收到最后一个文件名,此时程序被阻塞

最佳答案

问题出在 send 系统调用上。你用 MSG_MORE 标志调用它,这意味着更多数据将跟随并发送等待更多数据而不实际发送。您应该在没有此标志的情况下发送的最后一 block 数据。因此,您的服务器端应如下所示:

dp = readdir(dirp);
if (dp != NULL)
{
    /* each time check whether there are more data */
    while((dp_next = readdir(dirp))!= NULL)
    {
        r = send(fd, dp->d_name, 100, MSG_MORE);
        if (r < 0) {
            perror("\nsend");
        }
        printf("\n%s",dp->d_name);
        dp = dp_next;
    }

    /* send the last or the only record */
    r = send(fd, dp->d_name, 100, 0);
    if (r < 0) {
        perror("\nsend");
    }
}

解决此问题的另一种方法是使用 close(fd) 系统调用关闭连接。它在关闭连接之前发送缓冲区中的所有数据。这是一个不太干净但更简单的解决方案。

关于c - 无法接收使用 MSG_MORE 标志发送的最后一个套接字数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5829828/

相关文章:

java - 无法从输出流读取

java - 如何使用so-linger保持服务器连接一段时间

c# - 简单的 C# Http/TCP 服务器

c - 为什么一个正值的 int 在 c 中相加时会变成负值?

c - 在 c 中,如何使 1200/500 = 3

c - 在汇编代码中找不到跳转表

java - 从服务器向客户端发送响应

javascript - 通过 WebSockets 传输文本的正确方法是什么?

iphone - 使用 iPhone 应用程序中的 CONNECT 方法通过 SSL 实现 HTTP 代理

c - 重叠指针、类型的限制限定符的粒度