【问题标题】:C Winsock programming: input garbageC Winsock 编程:输入垃圾
【发布时间】:2024-01-08 06:35:01
【问题描述】:

我正在按照this sample code 编写一个非常简单的套接字服务器。服务器已启动并正在运行,我可以通过 telnet 连接到它(实际上是使用 Putty)。每当收到新连接时,我都会生成一个新线程,代码如下:

DWORD WINAPI receive_cmds(LPVOID lpParam) 
{
      char outbuffer[100];
      outbuffer[0] = '\0';
      char inbuffer[100];
      inbuffer[0] = '\0';
      int res;
      SOCKET current_client = (SOCKET)lpParam;

      while (1) {           
          res = recv(current_client, inbuffer, sizeof inbuffer - 1, 0);
          if (res > 0) {
              inbuffer[res] = '\0';
              printf("Got '%s'\n", inbuffer);
          }              
          Sleep(10);

          if (res == 0) {
             closesocket(current_client);
             ExitThread(0);             
          }                          

          //printf("%s\n", inbuffer); 
          strcpy(inbuffer, "");
      }
}

我一连接它就会打印出这个乱码:

如果我在客户端输入“hello”然后输入“*”,这就是我得到的:

即使我明确声明了行'\0'的结尾,它似乎占用了更多的行,而且我不知道为什么它会打印两次输入,第二次是第一个减去第一个一两个字符。

对了解正在发生的事情有任何帮助吗?提前致谢。

编辑:根据 unwind 的建议进行编辑

【问题讨论】:

    标签: c sockets


    【解决方案1】:

    你应该做更好的错误检查和更明智的缓冲区处理:

    res = recv(current_client, inbuffer, sizeof(inbuffer), 0);
    

    应该是

    res = recv(current_client, inbuffer, sizeof inbuffer - 1, 0);
    if (res > 0)
    {
      inbuffer[res] = '\0';
      printf("Got '%s'\n", inbuffer);
    }
    

    您需要在缓冲区中为终止符留出空间,因此您不能使用所有缓冲区来接收数据。您应该检查 -1,并在打印之前终止缓冲区以使其成为字符串。

    【讨论】:

    • 嗨!非常感谢,我现在离我越来越近了。一旦我连接我仍然得到“Got ”和双重输入问题,第二个是'\ n',我猜
    • @Alok:recv 的手册页说:“recv() 返回接收到的字节数,如果发生错误,则返回 -1”(稍微解释一下语法)。
    • @unwind:我的评论很抱歉,这是给@pistacchio 的——我想看看为什么他在做出你建议的更改后仍然胡言乱语。
    【解决方案2】:

    我猜 recv() 返回“-1”(表示错误)。

    我必须查看您的其余代码才能猜出原因。 尝试测试返回 -1,然后调用 WSAGetLastError() 找出错误原因。

    【讨论】: