KEEP K.I.S.S.

tk's blog

虚拟机socket通信丢失头字节奇怪问题一枚

tk posted @ Dec 28, 2012 04:25:48 PM in 业余 with tags linux socket 虚拟机 , 3091 阅读

问题描述:在虚拟机里的Linux上用socket TCP (C 编写)连接 Win 主机上 socket(python 编写) 服务器,获取的数据经常少一个字节,而且都是数据的头字节。使用 telnet 连接也是如此。在 Win 主机上用 Socket 调试工具和telnet 都是正常,不会丢失。

硬件环境:虚拟机为 Orcale VM VritualBox 4.1.2,虚拟机上系统为 Debian 6 x86-x64,虚拟机网络类型为 NAT。主机系统为 WinXP SP3 x86。

虚拟机linux下代码:

#include    "unp.h"

int
main(int argc, char **argv)
{
    int    sockfd, n;
    char    recvline[MAXLINE + 1];
    struct sockaddr_in    servaddr;

    if (argc != 2)
        err_quit("usage: a.out <IPaddress>");

    if ( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
        err_sys("socket error");

    bzero(&servaddr, sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    servaddr.sin_port   = htons(4013);    /* daytime server */
    if (inet_pton(AF_INET, argv[1], &servaddr.sin_addr) <= 0)
        err_quit("inet_pton error for %s", argv[1]);

    if (connect(sockfd, (SA *) &servaddr, sizeof(servaddr)) < 0)
        err_sys("connect error");

    while ( (n = read(sockfd, recvline, MAXLINE)) > 0) {
        recvline[n] = 0;    /* null terminate */
        printf("%d read from the socket\n", n);
        if (fputs(recvline, stdout) == EOF)
            err_sys("fputs error");
    }
    if (n < 0)
        err_sys("read error");

    exit(0);
}

这代码其实就是《UNIX 网络编程卷1》(UNP)中的第一个程序( unpv13e/intro/daytimetcpcli.c ),用 tcp 连接服务器,读取时间信息的。上述代码做了微小改动。UNP的第三版代码 unpv13e 可以在这里这里下载。

为了测试这个代码我在 Win 主机上用 python 写了一个服务程序:

import socket
import time

host = '192.168.1.68'
port = 4013

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((host, port))
s.listen(5)

while True:
    connection, address = s.accept()
    t = time.strftime("%a %X %x", time.localtime()).encode("ascii")
    c = connection.send(t)
    print("{0:d} sent of {1:d}: ".format(c, len(t)), "\"{0}\"".format(t.decode("ascii")), "TO client {0[0]}:{0[1]}".format(address))
    connection.close()

其中 192.168.1.68 是主机在局域网中的地址,绑定到这个地址上虚拟机中程序也可以访问到服务器。

当在虚拟机中用编译好的程序或者 telnet 访问 Win 上服务器时,经常会输出如下

"ri 16:22:52 12/28/12"

少了头部一个字符 "F" ,读取只是20个字节,但是也有时候正常,但是正常的几率低于 40%(目测)。

而在 Win 主机上打印输出都是正常的,'21 sent of 21:  "Fri 16:54:40 12/28/12" TO client 192.168.1.68:18289' 这样的,的确都是把 21 个字节发送完毕。

在 Win 主机上用 telnet 或者 TCP/UDP socket 调试助手来测试,获取的数据也都正常,为21字节,没有丢失头字节的情况发生。

(⊙﹏⊙) 

感觉可能是虚拟机 NAT 模式的问题或者还是什么,但是只丢失头字节的确是好奇怪。。。。

·-·-·-·-·-·--·-·-· 2012-12-29 分割线 -·-·-·-·-·-·-·-·--·-·-·-·

今天又测试了下,这次通信获取数据大部分情况下是正常的,只有约10%的几率会丢失头字节。在虚拟机里装了tcpdump 工具来看看情况。

两次通信

tisyang@debian:~/Sources/unpv13e/intro$ ./daytimetcpcli 192.168.1.68
20 read from the socket
at 09:14:47 12/29/12

tisyang@debian:~/Sources/unpv13e/intro$ ./daytimetcpcli 192.168.1.68
21 read from the socket
Sat 09:14:51 12/29/12

说明第一次通信丢失了头字节 'S',第二次通信正常。在此同时,我已经运行 tcpdump 来截获和主机 192.168.1.68 的通信包,命令和输出如下

tisyang@debian:~$ sudo tcpdump  host 192.168.1.68
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes

09:14:46.337897 IP 10.0.2.15.43314 > 192.168.1.68.4013: Flags [S], seq 3451477296, win 14600, options [mss 1460,sackOK,TS val 398218 ecr 0,nop,wscale 6], length 0
09:14:46.341664 IP 192.168.1.68.4013 > 10.0.2.15.43314: Flags [S.], seq 46272001, ack 3451477297, win 65535, options [mss 1460], length 0
09:14:46.341712 IP 10.0.2.15.43314 > 192.168.1.68.4013: Flags [.], ack 1, win 14600, length 0
09:14:46.341747 IP 192.168.1.68.4013 > 10.0.2.15.43314: Flags [S.], seq 46272001, ack 3451477297, win 65535, options [mss 1460], length 0
09:14:46.341837 IP 10.0.2.15.43314 > 192.168.1.68.4013: Flags [.], ack 1, win 14600, length 0
09:14:46.341865 IP 192.168.1.68.4013 > 10.0.2.15.43314: Flags [FP.], seq 1:21, ack 1, win 65535, length 20
09:14:46.342276 IP 10.0.2.15.43314 > 192.168.1.68.4013: Flags [F.], seq 1, ack 22, win 14600, length 0
09:14:46.342360 IP 192.168.1.68.4013 > 10.0.2.15.43314: Flags [.], ack 2, win 65535, length 0


09:14:49.632861 IP 10.0.2.15.43315 > 192.168.1.68.4013: Flags [S], seq 3496530236, win 14600, options [mss 1460,sackOK,TS val 399041 ecr 0,nop,wscale 6], length 0
09:14:49.633743 IP 192.168.1.68.4013 > 10.0.2.15.43315: Flags [S.], seq 46720001, ack 3496530237, win 65535, options [mss 1460], length 0
09:14:49.633771 IP 10.0.2.15.43315 > 192.168.1.68.4013: Flags [.], ack 1, win 14600, length 0
09:14:49.633983 IP 192.168.1.68.4013 > 10.0.2.15.43315: Flags [P.], seq 1:22, ack 1, win 65535, length 21
09:14:49.634048 IP 192.168.1.68.4013 > 10.0.2.15.43315: Flags [F.], seq 22, ack 1, win 65535, length 0
09:14:49.634245 IP 10.0.2.15.43315 > 192.168.1.68.4013: Flags [.], ack 22, win 14600, length 0
09:14:49.634749 IP 10.0.2.15.43315 > 192.168.1.68.4013: Flags [F.], seq 1, ack 23, win 14600, length 0
09:14:49.634815 IP 192.168.1.68.4013 > 10.0.2.15.43315: Flags [.], ack 2, win 65535, length 0

输出中的分段是我添加的,为了区分第一次通信和第二次通信。显然,第一次通信中就只获取到了 20 个字节(length 20),而第二次正常(length 21)。

TCP 连接要经过3次握手,而关闭需要4次握手,从第二次通信就可以看出来。

而在第一次通信中,3次握手tcp建立后,服务器很奇怪的发来一个 SYN 包,而且 FIN 包(用于连接终止)和 PUSH 包(传送数据)是在同一个包内。而在第二次通信里,没有这种情况。

 

Avatar_small
依云 说:
Dec 28, 2012 07:25:04 PM

wireshark 抓包看看吧

Avatar_small
tisyang 说:
Dec 29, 2012 08:50:16 AM

@依云: 今天重开虚拟机测试结果是大部分是正常地接收21字节。。只有约为 10% 的几率丢失头字节。。。我觉得可能就是虚拟机网络问题,我装个 tcpdump 看看

CBSE Class 6 Geograp 说:
Sep 26, 2022 01:13:39 PM

Geography is one of the Social Studies electives offered to board students in the Class 6th Grade. Every student has access to a chapter-wide sample paper with key questions that have been written on the board by professionals. CBSE Class 6 Geography Question Paper These review questions were created in accordance with the new test plan, which covers all board exam formats via the updated syllabus. A topic-wide practise question bank was created in Set-wide for all Class 6 chapters to the themes for all significant Geography concepts.

SEO 说:
Jun 11, 2023 10:15:04 PM

Thanks for a wonderful share. Your article has proved your hard work and experience you have got in this field. Brilliant .i love it reading. 링크모음

sophia 说:
Jun 21, 2023 08:02:10 PM

This is a great article thanks for sharing this informative information. I will visit your blog regularly for some latest post. I will visit your blog regularly for Some latest post. 평택출장마사지

sophia 说:
Jul 16, 2023 01:38:13 PM

Great Information sharing .. I am very happy to read this article .. thanks for giving us go through info.Fantastic nice. I appreciate this post. despre seriale

sophia 说:
Aug 30, 2023 04:08:24 PM

i read a lot of stuff and i found that the way of writing to clearifing that exactly want to say was very good so i am impressed and ilike to come again in future.. เว็บแทงบอลดีที่สุดUFABET

sophia 说:
Sep 03, 2023 11:16:19 PM

I definitely enjoying every little bit of it. It is a great website and nice share. I want to thank you. Good job! You guys do a great blog, and have some great contents. Keep up the good work. Fortune Tiger

seo service london 说:
Jan 16, 2024 02:50:19 PM

Actually I read it yesterday but I had some thoughts about it and today I wanted to read it again because it is very well written

jsimitseo 说:
Feb 02, 2024 05:37:51 PM

I expounded on a comparable issue, I give you the connection to my site.  best concierge doctor


登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter