TCP Socket没有接收数据,写/发送不超时?

时间:2010-11-24 16:19:11

标签: sockets unix solaris

我已经使用TCP套接字进行了多个项目和模拟,但这是我第一次遇到这个。

我在solaris sparc机器上有一个Linux服务器应用程序,它应该接受来自网络服务器上的OCX的连接,但是没有收到数据。我使用netstat来验证连接是否已建立。

我创建了一个小的tcp客户端来连接充当web服务器/ ocx,但是发生的事情是写入它停在那里并且永远不会发生超时。即使我离开了连接并等了几个小时,也没有任何反应。我甚至使用setsockopt来确保设置低超时值。另外,在另一端,不接收数据,并且在轮询fd集时select语句超时。

有没有人知道为什么写入或发送不会在写入sokcet时超时?另外,有没有人知道为什么在服务器上,没有设置读取fd集?

这是来自snoop的转储:

solaris61 -> 10.1.0.37    TCP D=8882 S=35111 Fin Ack=1805515051 Seq=897643511 Len=0 Win=49640
10.1.0.37 -> solaris61    TCP D=35111 S=8882 Ack=897643512 Seq=1805515051 Len=0 Win=24818
solaris61 -> 10.1.0.37    TCP D=8882 S=35112 Syn Seq=921698308 Len=0 Win=49640 Options=<mss 1460,nop,wscale 0,nop,nop,sackOK>
10.1.0.37 -> solaris61    TCP D=35112 S=8882 Syn Ack=921698309 Seq=1829645518 Len=0 Win=24820 Options=<nop,wscale 0,nop,nop,sackOK,mss 1460>
solaris61 -> 10.1.0.37    TCP D=8882 S=35112 Ack=1829645519 Seq=921698309 Len=0 Win=49640
solaris61 -> 10.1.0.37    TCP D=8882 S=35112 Push Ack=1829645519 Seq=921698309 Len=2 Win=49640
10.1.0.37 -> solaris61    TCP D=35112 S=8882 Ack=921698311 Seq=1829645519 Len=0 Win=24818

使用“snoop -x0 -s1500”

solaris61 - &gt; 10.1.0.37 TCP D = 8882 S = 35291 Syn Seq = 4205016629 Len = 0 Win = 49640选项=

   0: 0800 20f5 a3b5 000c 295d 6f44 0800 4500    .. .....)]oD..E.
  16: 0034 e4c7 4000 4006 0000 0a01 003d 0a01    .4..@.@......=..
  32: 0025 89db 22b2 faa3 7635 0000 0000 8002    .%.."...v5......
  48: c1e8 148a 0000 0204 05b4 0103 0300 0101    .è..............
  64: 0402                                       ..

10.1.0.37 - &gt; solaris61 TCP D = 35291 S = 8882 Syn Ack = 4205016630 Seq = 799808987 Len = 0 Win = 24820 Options =

   0: 000c 295d 6f44 0800 20f5 a3b5 0800 4500    ..)]oD.. .....E.
  16: 0034 c849 4000 4006 5e17 0a01 0025 0a01    .4.I@.@.^....%..
  32: 003d 22b2 89db 2fac 1ddb faa3 7636 8012    .=".../.....v6..
  48: 60f4 8ec1 0000 0103 0300 0101 0402 0204    `...............
  64: 05b4                                       ..

solaris61 - &gt; 10.1.0.37 TCP D = 8882 S = 35291 Ack = 799808988 Seq = 4205016630 Len = 0 Win = 49640

   0: 0800 20f5 a3b5 000c 295d 6f44 0800 4500    .. .....)]oD..E.
  16: 0028 e4c8 4000 4006 0000 0a01 003d 0a01    .(..@.@......=..
  32: 0025 89db 22b2 faa3 7636 2fac 1ddc 5010    .%.."...v6/...P.
  48: c1e8 147e 0000                             .è.~..

solaris61 - &gt; 10.1.0.37 TCP D = 8882 S = 35291按Ack = 799808988 Seq = 4205016630 Len = 2 Win = 49640

   0: 0800 20f5 a3b5 000c 295d 6f44 0800 4500    .. .....)]oD..E.
  16: 002a e4c9 4000 4006 0000 0a01 003d 0a01    .*..@.@......=..
  32: 0025 89db 22b2 faa3 7636 2fac 1ddc 5018    .%.."...v6/...P.
  48: c1e8 1480 0000 750a                        .è....u.

10.1.0.37 - &gt; solaris61 TCP D = 35291 S = 8882 Ack = 4205016632 Seq = 799808988 Len = 0 Win = 24818

   0: 000c 295d 6f44 0800 20f5 a3b5 0800 4500    ..)]oD.. .....E.
  16: 0028 c84a 4000 4006 5e22 0a01 0025 0a01    .(.J@.@.^"...%..
  32: 003d 22b2 89db 2fac 1ddc faa3 7638 5010    .=".../.....v8P.
  48: 60f2 cf8c 0000 5555 5555 5555              `.....UUUUUU

solaris61 - &gt; 10.1.0.37 TCP D = 8882 S = 35291 Fin Ack = 799808988 Seq = 4205016632 Len = 0 Win = 49640

   0: 0800 20f5 a3b5 000c 295d 6f44 0800 4500    .. .....)]oD..E.
  16: 0028 e4ca 4000 4006 0000 0a01 003d 0a01    .(..@.@......=..
  32: 0025 89db 22b2 faa3 7638 2fac 1ddc 5011    .%.."...v8/...P.
  48: c1e8 147e 0000                             .è.~..

10.1.0.37 - &gt; solaris61 TCP D = 35291 S = 8882 Ack = 4205016633 Seq = 799808988 Len = 0 Win = 24818

   0: 000c 295d 6f44 0800 20f5 a3b5 0800 4500    ..)]oD.. .....E.
  16: 0028 c84b 4000 4006 5e21 0a01 0025 0a01    .(.K@.@.^!...%..
  32: 003d 22b2 89db 2fac 1ddc faa3 7639 5010    .=".../.....v9P.
  48: 60f2 cf8b 0000 5555 5555 5555              `.....UUUUUU

2 个答案:

答案 0 :(得分:1)

下到tcpdump(1)和/或snoop(1M),查看双方电线上发生的情况。考虑到您描述的“魔法”,这可能是找到解释的最佳选择。发现更多细节。

答案 1 :(得分:0)

如果没有收到已发送内容的TCP确认,则只会超时。您的转储显示已确认所有已发送的数据,因此不应该没有超时。发送的唯一数据是来自solaris61的2个字节。

听起来你说你打算向solaris61发送一些数据。此数据从未发送过。你是如何发送这些数据的?如果使用缓冲的stdio编写,则数据可能仍在缓冲区中。例如,如果它是行缓冲的,那么它将被缓冲,直到发送换行符。相反,您可以使用setvbuf()关闭缓冲,或者只使用send()直接发送数据。

(如果您已经这样做,那么请发布该部分代码。)