Winsock:Echo服务器应答两次,当时我刚刚将其编程为执行一个send()调用 我正在C++中做一个简单的TCP服务器,用于Windows呼入数据。我有个问题。在我解释我的问题之前,我必须说Winsock设置正确,这个问题发生在任何IP地址作为源的情况下

Winsock:Echo服务器应答两次,当时我刚刚将其编程为执行一个send()调用 我正在C++中做一个简单的TCP服务器,用于Windows呼入数据。我有个问题。在我解释我的问题之前,我必须说Winsock设置正确,这个问题发生在任何IP地址作为源的情况下,c++,windows,winsock2,C++,Windows,Winsock2,建立连接时的一般行为如下: 在连接仍处于活动状态时运行的循环中,它必须回显数据,并在其前面加上回复字 为此,我目前正在使用两个send()调用: 一个电话单独发送“应答” 另一个电话只是发送回收到的数据 但使用Putty客户端,我得到了以下结果: 回复数据\u回显回复 如果是第一个发送呼叫,为什么在最后一个发送呼叫之后发送应答???我将在出现问题的地方发布一段代码: //Reply to client message = "HELLO CLIENT!! READY TO ECHO.\n";

建立连接时的一般行为如下:

在连接仍处于活动状态时运行的循环中,它必须回显数据,并在其前面加上回复字

为此,我目前正在使用两个send()调用:

  • 一个电话单独发送“应答”
  • 另一个电话只是发送回收到的数据
但使用Putty客户端,我得到了以下结果: 回复数据\u回显回复

如果是第一个发送呼叫,为什么在最后一个发送呼叫之后发送应答???我将在出现问题的地方发布一段代码:

//Reply to client
message = "HELLO CLIENT!! READY TO ECHO.\n";
send(new_socket, message, strlen(message), 0);

///Enter into a loop until connection is finished.
printf("%s \n\n", "Incoming data goes here: ");
do{

    ///Clear buffer and receive data.
    memset(buffer, 0, sizeof(buffer));
    ret = recv(new_socket, buffer, sizeof(buffer), 0);


    printf("%s", buffer);

    ///Send a REPLY WORD and the data echoed.
    send(new_socket, "REPLY\r\n", 7, 0);
    send(new_socket, buffer, sizeof(buffer), 0);

}while(ret != SOCKET_ERROR);

这有什么不对?我将删除第一个呼叫,双重效果将消失。为什么我不能一个接一个地发送两个呼叫?

在发送
REPLY
之前,忽略
recv
的返回值,因此无论发生什么情况,都会发送
REPLY
,然后发送缓冲区的内容。在您第一次回显后,会发生一些事情,无论是什么,您都会发送
REPLY

坦率地说,您似乎并不了解TCP的基本知识。我们曾经有一条规则,在任何人可以使用TCP做任何事情之前,他们必须记住并完全理解以下语句:“TCP是一种字节流协议,不保留应用程序消息边界。”

您的代码假装正在接收和回显应用程序级消息。但是没有代码来实际实现应用程序级消息。TCP不支持应用程序级消息,因此如果需要,必须实现它们。你显然想要它们。您还没有实现它们


换行符是否分隔消息?如果是这样,在数据流中查找它们的代码在哪里?如果没有,怎么办?

我并不是说这是问题的根本原因,但请注意,您正在将整个缓冲区sizeof(buffer)发送回客户端,尽管您可能收到的字节数比sizeof(buffer)要少@ShmilTheCat我用Putty尝试过,它似乎可以正确地发送回数据,但只是添加了一个“回复”字。我在写我自己的客户端时测试了它,它发送给我1000字节,这是预期的数量。但当我只使用one时,它会继续执行double send(),您在哪里为
ret
赋值?另外,尝试null终止接收到的缓冲区和/或发送
strlen(缓冲区)
@Brandon我这样做了。我认为ret不需要初始化,但我初始化了它,没有任何变化。此外,我还以null结尾字符串,但问题仍然存在。我首先使用字符串作为测试用例,然后如果问题得到解决,我将切换到二进制数据。@DeanWinchester它导致了错误。这是导致此错误的一种方法。这将导致您打印并回显尚未收到的数据,这正是您描述的问题。在调用
recv()
之后立即添加
if(ret==0)break
。类似地,您应该在调用
recv()
之后立即测试-1,而不是执行所有发送然后检查。谢谢您的回答,这意味着包是以随机顺序到达的???我想如果我发送A,B,C,我必须得到A,B,C。如果我犯了初学者的错误,我很抱歉,我没有很多时间编程。你在写应用程序级的代码。在应用程序级别没有“包”。网络上发生的事情是TCP的事情。应用程序发送字节和接收字节,因为TCP是提供字节流的字节流协议。如果您先发送“你好”再发送“再见”,您可能会收到“HELLOGOODBYE”,或者您可能会收到“H”再发送“ELLOGOODBYE”。TCP不保留应用程序消息边界。TCP不支持应用程序级消息。如果你想要消息(很明显你想要),你必须对它们进行编码(很明显你没有)。