Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/71.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 如何知道send()或sendmsg()成功传递消息?_C_Sockets_Send_Sendto - Fatal编程技术网

C 如何知道send()或sendmsg()成功传递消息?

C 如何知道send()或sendmsg()成功传递消息?,c,sockets,send,sendto,C,Sockets,Send,Sendto,我设置了一个简单的客户端和服务器程序,使用TCP套接字进行通信。服务器等待客户端连接并答复是否从客户端接收到消息。下面是代码在服务器和客户端中的实现方式: 服务器端的代码: listen(sockfd,5); clilen = sizeof(cli_addr); newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen); if (newsockfd < 0) error("E

我设置了一个简单的客户端和服务器程序,使用TCP套接字进行通信。服务器等待客户端连接并答复是否从客户端接收到消息。下面是代码在服务器和客户端中的实现方式:

服务器端的代码:

 listen(sockfd,5);

 clilen = sizeof(cli_addr);
 newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen);

 if (newsockfd < 0)
      error("ERROR on accept");
 bzero(buffer,256);

 n = read(newsockfd,buffer,255);

 if (n < 0)
     error("ERROR reading from socket");

 printf("Here is the message: %s\n",buffer);

 n = write(newsockfd,"I got your message",18);

 if (n < 0)
     error("ERROR writing to socket");
倾听(sockfd,5);
clilen=sizeof(cli_addr);
newsockfd=accept(sockfd,(struct sockaddr*)&cli\u addr,&clilen);
if(newsockfd<0)
错误(“接受错误”);
b0(缓冲器,256);
n=读取(newsockfd,缓冲区,255);
if(n<0)
错误(“从套接字读取错误”);
printf(“这是消息:%s\n”,缓冲区);
n=写(newsockfd,“我收到你的消息”,18);
if(n<0)
错误(“写入套接字时出错”);
客户端上的代码:

if (connect(sockfd,(struct sockaddr *)&serv_addr,sizeof(serv_addr)) < 0)
    error("ERROR connecting");
printf("Please enter the message: ");
bzero(buffer,256);
fgets(buffer,255,stdin);
n = write(sockfd,buffer,strlen(buffer));
if (n < 0)
     error("ERROR writing to socket");
else
    printf("sucess. n = %d", n);

bzero(buffer,256);
n = read(sockfd,buffer,255);
if (n < 0)
     error("ERROR reading from socket");
if(connect(sockfd,(struct sockaddr*)&serv_addr,sizeof(serv_addr))<0)
错误(“连接错误”);
printf(“请输入消息:”);
b0(缓冲器,256);
fgets(缓冲区,255,标准输入);
n=写入(sockfd,buffer,strlen(buffer));
if(n<0)
错误(“写入套接字时出错”);
其他的
printf(“成功n=%d”,n);
b0(缓冲器,256);
n=读取(sockfd,缓冲区,255);
if(n<0)
错误(“从套接字读取错误”);
现在,假设我启动服务器,然后启动客户机,客户机成功连接到服务器。然后我关闭服务器并尝试从客户端发送消息,
write()
操作不会返回任何错误。我在这里所期望的是一个错误,因为服务器实际上没有收到任何数据包(它已关闭)


所以我的问题是:有没有办法知道
write()
(或
send()
sendto()
sendmsg()
)是否成功地将消息传递到服务器?

它不是这样工作的。消息放入发送缓冲区后,write()立即返回success。要知道该消息是由服务器接收和处理的,唯一的方法是通过解析“我收到了你的消息”来接收电子邮件


write()返回-1,则连接已被关闭或无效,但不要指望它检测所有可能的错误。

它不是这样工作的。消息放入发送缓冲区后,write()立即返回success。要知道该消息是由服务器接收和处理的,唯一的方法是通过解析“我收到了你的消息”来接收电子邮件


write()返回-1,则已知连接已关闭或无效,但不要指望它来检测所有可能的错误。

否。write或send只需进行对话,它们不会等待反馈(例如TCP情况下的ACK)。但是,只有得到某种反馈,你才能确保信息成功传递。尝试另一次发送甚至没有帮助,因为它可能在上一条消息尚未到达客户端时执行。这也无助于记录并希望出错,因为您收到的数据可能在您发送消息之前就已经由对等方发送了。唯一能真正确定的方法是在应用程序协议中加入某种明确的握手,然后等待与您的消息匹配的响应。

否。只需编写或发送对话,他们不会等待反馈(例如TCP中的ACK)。但是,只有得到某种反馈,你才能确保信息成功传递。尝试另一次发送甚至没有帮助,因为它可能在上一条消息尚未到达客户端时执行。这也无助于记录并希望出错,因为您收到的数据可能在您发送消息之前就已经由对等方发送了。唯一能真正确定的方法是在应用程序协议中加入某种明确的握手,然后等待消息的匹配响应。

第一段是正确的,但第二段中有太多错误信息。write()仅在传递零长度时返回零。如果在关闭的套接字上调用它,它将返回-1,并将errno设置为EBADF。如果在对等方关闭的连接上调用它,它将返回-1,并将errno设置为ECONNRESET-1本身并不表示“无效连接”。感谢您的修改!好的,我们的想法是修正答案。第一段是正确的,但是第二段有太多的错误信息。write()仅在传递零长度时返回零。如果在关闭的套接字上调用它,它将返回-1,并将errno设置为EBADF。如果在对等方关闭的连接上调用它,它将返回-1,并将errno设置为ECONNRESET-1本身并不表示“无效连接”。感谢您的修改!这个想法实际上是为了解决这个问题。我搜索了这个问题,似乎当服务器停止时,会向客户端发送一个SIGPIPE信号,但我仍然不知道客户端是如何捕获和处理这个信号的。比如:如果TCP连接关闭,您尝试发送()或写入()再次得到一个SIGIPE,或者如果忽略该信号,系统调用将返回EPIPE。但事实并非如此,服务器向客户端发送信号,它只是关闭了连接。我搜索了这个问题,发现当服务器停止时,一个SIGPIPE信号被发送到客户端,但我仍然不知道客户端是如何捕获和处理此信号的。类似于:如果TCP连接关闭,您尝试发送()或写入()再次得到一个SIGIPE,或者如果忽略该信号,系统调用将返回EPIPE。但事实并非如此,服务器向客户端发送信号,它只是关闭连接。许多人问,“如果TCP堆栈知道远程主机已确认(确认)该数据包,为什么我的应用程序代码无法确定这一点?”原因是TCP只知道数据包是否由远程主机的TCP层确认。它不知道正在确认的数据是否被托管远程套接字的应用程序实际使用。因此,TCP之上的更高级别协议(即您的代码和协议