Linux中tcp接收数据包时粘包的问题
我刚刚开始学习tcp的socket编程,在实际工作中遇到这样的困难,各位大侠,请多多指教啊。
用tcp协议进行视频帧发送接收,每帧定义帧序号、帧类型、帧长度(依照数据会随机改变)、帧数据等信息。
在接收方,为了提高接收效率,设置的缓冲区为1000KB,在实际运行中,收到的帧序号、帧长度有乱的,网上查了半天,可能为粘包了。
对于tcp接收数据包出现粘包的问题,一知半解的,请各位支个招,怎么样解决,怎样分包出来,能提供代码有助于理解,那是万万感谢了。 "在接收方,为了提高接收效率,设置的缓冲区为1000KB,在实际运行中,收到的帧序号、帧长度有乱的,网上查了半天,可能为粘包了。"
首先, 设置大缓冲区与接收效率没有直接关系, 只有缓冲区是瓶颈的时候才会有影响. 实际上和你处理程序的关系很大.
粘包本来就是正常的........"收到的帧序号、帧长度有乱的," 这个主要看你程序怎么处理的接收到的数据.
tcp里没有包的概念, 只有数据流的概念! 你 可以想象tcp的缓冲区为一个篮子, 发送方向篮子里放数据, 接收方从篮子里取数据, 缓冲区的存在, 可以说就是为了粘包的........
我推测问题出在你的处理程序.
把socket处理那段发上来看看吧 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;
//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); 怎么没人啊。天~~~ 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用的莫名其妙啊....... 呵呵,初学者,很多不足之处,请多多指教。
页:
[1]