【问题标题】:C TCP Server doesn't send data before closingC TCP Server在关闭前不发送数据
【发布时间】:2016-02-04 12:38:31
【问题描述】:

我正在尝试在两台 Ubuntu 计算机之间建立 TCP 连接。 服务器应该向客户端发送单个字符值。客户端应该打印这些字符。 在服务器和客户端之间建立连接似乎按预期工作,但是当我调用 send() 时,客户端没有输出。

实现输出的唯一方法是在无限循环中发送相同的字符值,这会导致在客户端控制台中打印无限数量的字符,或者通过更改客户端代码中的 if 语句(请参阅下面的代码)从 if(len > 0) 到 if(len >= 0)。在这种情况下,只要我通过 CTRL + C 关闭服务器,发送的字符就会正确打印,但它也会多次打印最后传输的字符。因此,当服务器仍在运行时,我无法在客户端接收值。

这是服务器的代码:

int serverSocket = socket(AF_INET, SOCK_STREAM, 0);
struct sockaddr_in adresse;
adresse.sin_family = AF_INET;
adresse.sin_addr.s_addr = INADDR_ANY;
adresse.sin_port = htons (2457);

bind ( serverSocket, (struct sockaddr *) &adresse, sizeof (adresse))
listen (serverSocket, 1);

while(1)
{
socklen_t adrlen = sizeof(struct sockaddr_in);
int conSocket= accept ( serverSocket, (struct sockaddr *) &adresse, &adrlen ); 
if(conSocket => 0)
{
    char charToSend;
    while(1)
    {
        charToSend = returnChar();
        if(send(conSocket= , &charToSend, 1, 0) == -1)
        {
            printf("Error\n"); 
        } 
    }
    close(conSocket);           
}
close(serverSocket);
}

这是客户的代码:

int clientSocket = socket(AF_INET, SOCK_STREAM, 0);
struct sockaddr_in adresse;
adresse.sin_family = AF_INET;
adresse.sin_port = htons (2457);
inet_aton ("192.168.2.101", &adresse.sin_addr);

if (connect ( clientSocket, (struct sockaddr *) &adresse, sizeof (adresse)) == 0)
{               
while(1)
{
    char recvd[2];
    int len = recv(clientSocket, recvd, 1, 0);
    recvd[1] = '\0';
    if(len > 0)
    {
            printf("%s", recvd);
    }
}
}

服务器代码中的函数 returnChar() 用于处理来自传感器的信息并返回一个 char 值。在处理完一个完整的信号之前它不会终止,同时正在运行一个循环。

我唯一的想法是 send() “没有时间”在程序继续另一个循环之前发送值。这可能是问题吗?还是我在客户端的代码中做错了什么?

【问题讨论】:

标签: c linux sockets tcp


【解决方案1】:

在我看来,问题出在客户端。您打印没有行终止的字符。因此,所有内容都缓冲在客户端标准输出流中。请在 printf 中添加'\n' 为:printf("%s\n", recvd);

【讨论】:

  • 我同意。您还可能遇到 TCP 堆栈正在缓冲的问题,除非发送了 PUSH,告诉远程端即使缓冲区尚未满也将数据传送到应用程序。类似的问题,但在网络协议中。
  • 这也是一种解决方案,但 John Hascall 的回答使得将所有字符保留在一行中成为可能。谢谢!
【解决方案2】:

实际上,问题可能出在客户端。 使您的客户端的输出无缓冲:

setvbuf(stdout, NULL, _IONBF, (size_t)0);

或者干脆使用无缓冲的,而不是标准的(缓冲的)I/O:

write(fileno(stdout), recvd, (size_t)1);

虽然,由于您的流量是单向的,使用 TCP_NODELAY 的建议将有助于加快发送速度。

【讨论】:

  • 谢谢,我真的不相信这是客户端问题。现在一切正常。
猜你喜欢
  • 2018-12-25
  • 1970-01-01
  • 2021-02-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-10-08
相关资源
最近更新 更多