C语言]socket send成功返回但是对面未能成功收到。

owlwol 2009-07-09 05:47:09
我是看的一Unix下开源产品源代码,服务器客户端模型,C语言编写。

问题是这样的,服务端在处理完请求后返回一个确认字串给客户端(几个字节),而客户端读取服务端的返回失败,检测到根本就没有读到内容,从而引发了一些其它的问题。

通过检查服务端,我发现返回的地方就是一个简单的send函数,而且通过检查发现返回值正常。

我知道send只是将内容copy到socket对应的缓冲区,只要copy成功就返回成功。所以问题应该在后面,不过现在暂时不知道如何去侦测。



在别的论坛上又有人建议我抓包,最后抓过来分析了。

用tcpdump抓包,与服务器和客户端的调试数据做对比,情况如下。

出错是在第446284(此数不一定,每次情况不同)次操作,从抓到的包来看,只看到这一条的客户端请求,并没有发现有服务器返回的包。

所以判断应该是服务器端返回没有成功,也就是上面说的,它只是将返回内容copy到了socket的缓冲区,但是最终的发送失败了。

然而服务器的错误追踪到send之后,也就是说send成功后内核在输出socket缓冲区的时候出错了。这个东西。。。。。有点不知道如何是好了。

请大家指教。。
...全文
914 15 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
owlwol 2009-07-10
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 linren 的回复:]
int send_len;

send_len=send(sock,msg,len,0);
if(send_len==-1){
printf("%d\n",errno);
perror("send");
}
[/Quote]

您好,send操作没有出错,我打印了send_len是正常的msg长度。
lwh_1024 2009-07-10
  • 打赏
  • 举报
回复
会不会是你的客户端在发送请求后,没有等到服务端返回就断掉了连接?
把代码贴上来看看吧
linren 2009-07-10
  • 打赏
  • 举报
回复
int send_len;

send_len=send(sock,msg,len,0);
if(send_len==-1){
printf("%d\n",errno);
perror("send");
}
linren 2009-07-10
  • 打赏
  • 举报
回复
查看一下errno
liliangbao 2009-07-10
  • 打赏
  • 举报
回复
帮顶!
owlwol 2009-07-10
  • 打赏
  • 举报
回复
大哥说的什么意思,不太明白

[调用send的线程]
这个没什么说的

[收到数据的事件响应线程]
这个我横竖理解都没想通。

还请详细指教。
rainbow_free 2009-07-10
  • 打赏
  • 举报
回复
友情帮顶!
owlwol 2009-07-10
  • 打赏
  • 举报
回复
谢谢,MC的socket确实是用noblocking的,听从您的建议查看了errno,确实有错。115号错误。

Operation now in progress

近一步在网上找的资料里看到一些解释:

The socket is marked as nonblocking. The connection cannot be immediately completed. The application program can select the socket for writing during the connection process.

网上说这个东西可以乎略,我理解的是传输过程慢了,导致客户端等不急而放弃了读取。但是无论如何,是不是服务端的信息会传过来呢?我用tcpdump能够抓到吧。但是结果是没有抓到这个包。所以我不觉得是客户端的问题。

通过先前的判断我一直认为是服务端的问题。因为包根本就没能传过来,服务端send成功为止。那个返回给客户端的包也没能在服务器端抓到,也就是说他根本就没有传出去。

更多信息:
客户端是MC的客户端,可以说已经比较成熟稳定了,而服务端是tokyotyrant,他支持MC协议,比较新。我想问题还是应该在服务端上,关于send机制,我理解的也只有主贴中说的那么多。请高人赐教。


[Quote=引用 11 楼 saturn255 的回复:]
是不是你客户端是超时模式?在未从socket缓冲中拿到服务器发送的数据就超时返回了?

建议在
if (buf) {
786        MMC_DEBUG(("mmc_readline: read data:"));
787        MMC_DEBUG(("%s", buf));
788        return strlen(buf);
789    } 
790    else {
791        MMC_DEBUG(("mmc_readline: cannot read a line from the server"));
792        return -1;
793    } 

else里查看下errno~~~
[/Quote]
赵4老师 2009-07-10
  • 打赏
  • 举报
回复
各位大虾,你们知道吗?
真正的原因是调用send的线程必须和收到数据的事件响应线程不是同一个线程!
不信的话,楼主你改用另一个线程send试试。
kojie_chen 2009-07-10
  • 打赏
  • 举报
回复
如果 send返回成功,肯定是已经发送成功了,只是在客户端接收的问题,缓冲区够大么
saturn255 2009-07-10
  • 打赏
  • 举报
回复
是不是你客户端是超时模式?在未从socket缓冲中拿到服务器发送的数据就超时返回了?

建议在
if (buf) {
786 MMC_DEBUG(("mmc_readline: read data:"));
787 MMC_DEBUG(("%s", buf));
788 return strlen(buf);
789 }
790 else {
791 MMC_DEBUG(("mmc_readline: cannot read a line from the server"));
792 return -1;
793 }

else里查看下errno~~~
lijiawlm 2009-07-10
  • 打赏
  • 举报
回复
如果是UDP 发送成功不成功 不知道
如果是TCP 发送成功 绝对就是客户端收到了
owlwol 2009-07-10
  • 打赏
  • 举报
回复
谢谢各位帮忙分析帮忙顶!
owlwol 2009-07-10
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 lwh_1024 的回复:]
会不会是你的客户端在发送请求后,没有等到服务端返回就断掉了连接?
把代码贴上来看看吧
[/Quote]

服务端是tokyotyrant,客户端是memcahced的PHP扩展代码。应该不是您说的这种情况,MC的php扩展代码中读服务器返回的代码如下:

775 static int mmc_readline(mmc_t *mmc TSRMLS_DC) /* {{{ */
776 {
777 char *buf;
778
779 if (mmc->stream == NULL) {
780 MMC_DEBUG(("mmc_readline: socket is already closed"));
781 return -1;
782 }
783
784 buf = php_stream_gets(mmc->stream, mmc->inbuf, MMC_BUF_SIZE);
785 if (buf) {
786 MMC_DEBUG(("mmc_readline: read data:"));
787 MMC_DEBUG(("%s", buf));
788 return strlen(buf);
789 }
790 else {
791 MMC_DEBUG(("mmc_readline: cannot read a line from the server"));
792 return -1;
793 }
794 }

上面的代码,php_stream_gets是执行了的,不过执行的结果是buf为null。于是下面进入else,return -1.

owlwol 2009-07-09
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 luwenzuo 的回复:]
所谓的成功,不管你是用怎么模式,都是发送到客户端确认后,send才返回成功发送数;

只是模式适应不同情况而已,
[/Quote]

好像不是呢,send只是将数据copy到socket的缓冲区内就会返回的吧。

见:http://blog.csdn.net/zhh157/archive/2008/11/11/3273538.aspx
大前置 2009-07-09
  • 打赏
  • 举报
回复
所谓的成功,不管你是用怎么模式,都是发送到客户端确认后,send才返回成功发送数;

只是模式适应不同情况而已,

70,025

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧