打印
[嵌入式linux]

Linux中tcp接收数据包时粘包的问题

[复制链接]
3295|5
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
77muke|  楼主 | 2010-9-16 09:36 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
我刚刚开始学习tcp的socket编程,
在实际工作中遇到这样的困难,各位大侠,请多多指教啊。
用tcp协议进行视频帧发送接收,每帧定义帧序号、帧类型、帧长度(依照数据会随机改变)、帧数据等信息。
在接收方,为了提高接收效率,设置的缓冲区为1000KB,在实际运行中,收到的帧序号、帧长度有乱的,网上查了半天,可能为粘包了。
对于tcp接收数据包出现粘包的问题,一知半解的,请各位支个招,怎么样解决,怎样分包出来,能提供代码有助于理解,那是万万感谢了。

相关帖子

沙发
sinanjj| | 2010-9-16 10:54 | 只看该作者
"在接收方,为了提高接收效率,设置的缓冲区为1000KB,在实际运行中,收到的帧序号、帧长度有乱的,网上查了半天,可能为粘包了。"

首先, 设置大缓冲区与接收效率没有直接关系, 只有缓冲区是瓶颈的时候才会有影响. 实际上和你处理程序的关系很大.

粘包本来就是正常的........"收到的帧序号、帧长度有乱的," 这个主要看你程序怎么处理的接收到的数据.
tcp里没有包的概念, 只有数据流的概念! 你 可以想象tcp的缓冲区为一个篮子, 发送方向篮子里放数据, 接收方从篮子里取数据, 缓冲区的存在, 可以说就是为了粘包的........

我推测问题出在你的处理程序.

把socket处理那段发上来看看吧

使用特权

评论回复
板凳
77muke|  楼主 | 2010-9-16 13:55 | 只看该作者
int sockfd,newsockfd;
        int ret;
        int ret1;

        struct sockaddr_in my_addr,their_addr;

        sockfd = socket(AF_INET, SOCK_STREAM, 0);

        if (sockfd == -1)
        {
                perror("socket");
                exit(1);
        }

        my_addr.sin_family = AF_INET;
        my_addr.sin_port = htons(6006);
        my_addr.sin_addr.s_addr = inet_addr("192.168.9.140");
        bzero(&(my_addr.sin_zero), 8);

        if ((bind(sockfd, (struct sockaddr *) &my_addr, sizeof(struct sockaddr)))== -1)
                {
                        perror("bind");
                        close(sockfd);

                        exit(1);
                }

        ret1=listen(sockfd,20);
        if(ret1==-1)
        {
                perror("listen");
                printf("listening:%d",ret1);
                exit(1);
        }

        char buf[100<<10];
        //char *new_buf;
        //int total=0;
       
        do
        {
                unsigned int addr_len = sizeof(struct sockaddr);
                if ((newsockfd = accept(sockfd, (struct sockaddr *) &their_addr, &addr_len))        < 0)
                        {
                                perror("accept");
                          continue;
                        }
                else
                        {
                                        printf("accepted a new connecttion.\n");
               
                                        pid_t fpid; //fpid表示fork函数返回的值
               
                      fpid = fork();
                                        if (fpid < 0)
                                        {
                                                printf("error in fork!");
                                        }  
                                        else if (fpid == 0)
                                        {
                                                printf("i am the child process, my process id is %d\n",getpid());
                                               
                                                fd_set rfd;
                                                struct timeval timeout;
                                                timeout.tv_sec = 30;
                                                timeout.tv_usec = 0;
                                                FD_ZERO(&rfd);
                                                FD_SET(newsockfd,&rfd);
                               
                               
                                                if ((select(newsockfd + 1, &rfd, NULL, NULL, &timeout)) == -1)
                                                        perror("select");
                                                else if ((select(newsockfd + 1, &rfd, NULL, NULL, &timeout)) == 0)
                                                        {
                                                                printf("time out\n");
                                                                close(newsockfd);
                                                        }                                                       
                               
                                                else
                                                {
                                                        memset(buf, 0, sizeof(buf));
                                                       
                                                        ret = recv(newsockfd, buf, 100 << 10, 0);
                                                        if (ret == -1)
                                                        {
                                                                perror("recv");
                                                                close(newsockfd);
                                                                exit(1);
                                                        }
                                                        else
                                                        {
                                                                        xedex_t *dex_p = (xedex_t *) buf;
                                                                        frame_seq = dex_p->U.frame.seq;
                                                                        frame_date_len=dex_p->U.frame.data_len;
                                                                       
                                                                       
                                                                        printf("frame_seq=%d,frame_date_len=%d,ret=%d\n",frame_seq,frame_date_len,ret);
                                                        }
                                                }
                                        else                                                                                                               
                                        {
                                                printf("i am the parent process, my process id is %d\n",getpid());
                                                close(newsockfd);
                                        }
                                }
        } while (1);

使用特权

评论回复
地板
77muke|  楼主 | 2010-9-16 16:59 | 只看该作者
怎么没人啊。天~~~

使用特权

评论回复
5
sinanjj| | 2010-9-16 17:54 | 只看该作者
3# 77muke

                    
                                                        ret = recv(newsockfd, buf, 100 << 10, 0);
                                                        else
                                                        {
                                                                        xedex_t *dex_p = (xedex_t *) buf;
                                                                        frame_seq = dex_p->U.frame.seq;
                                                                        frame_date_len=dex_p->U.frame.data_len;
                                                                    

这个地方, 应该先看看收到了多少字节, 符合要求不, 字节数不够接续接受.......


我就纳闷, 这程序什么编写思路....... select用的莫名其妙啊.......

使用特权

评论回复
6
77muke|  楼主 | 2010-9-16 20:57 | 只看该作者
呵呵,初学者,很多不足之处,请多多指教。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

34

主题

78

帖子

0

粉丝