目的是在一个A8的板子上跑一个H.264的解码器,使用了socket进行码流传输,直接运行程序,client无法正确接收到码流数据,但是使用GDB进行跟踪调试时,包又可以正确接收。
每次发送的数据大部分时候都超过16K
// --server端的代码
int main(int argc, char** argv)
{
int servfd,clifd;
FILE *fin = NULL;
int numPacket = 0;
int sendLen = 0;
struct sockaddr_in servaddr,cliaddr;
unsigned char *currData = NULL;
unsigned int x, j, k;
unsigned int dataLen = 0;
int curFlags = 0;
int packetCnt = 0;
if ((servfd = socket(AF_INET,SOCK_STREAM, 0 )) < 0 )
{
printf( " create socket error!\n " );
exit( 1 );
}
//bzero( & servaddr, sizeof (servaddr));
memset(&servaddr,0,sizeof (servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(SERVER_PORT);
servaddr.sin_addr.s_addr = htons(INADDR_ANY);
if (bind(servfd,( struct sockaddr * ) & servaddr, sizeof (servaddr)) < 0 )
{
printf( " bind to port %d failure!\n " ,SERVER_PORT);
exit( 1 );
}
if (listen(servfd,LENGTH_OF_LISTEN_QUEUE) < 0 )
{
printf( " call listen failure!\n " );
exit( 1 );
}
// get the h264 file name!
long timestamp;
socklen_t length = sizeof (cliaddr);
clifd = accept(servfd,( struct sockaddr * ) & cliaddr, & length);
char buf[255];
length = recv(clifd, buf, 255, 0);
if (length < 0)
{
printf( " error comes when recieve data from server %s! ", argv[1] );
exit( 1 );
}
buf[length] = '\0';
printf("Get filename from client%s,%d\n",buf,length);
fin = fopen(buf,"rb");
if(fin == NULL)
{
printf("Can't open file, check if the file is exist\n");
exit(-1);
}
printf("0x%p\n",dataBuf);
while ( 1 )
{
dataLen = ReadLenOnePicData(dataBuf,fin); // 获得一副图像的数据,每次的大小不一样
if(dataLen > 0)
{
numPacket = 1;
sendLen = dataLen;
if(dataLen > 16384)
{
// 当数据长度超过16K时,拆分成多个包传输。
numPacket = dataLen / 16384;
if((dataLen % 16384) != 0)
{
numPacket++;
}
sendLen = 16384;
}
send(clifd,&numPacket,4,0); // tell the client curr
currData = dataBuf;
printf("numPacket =%d,dataLen=%d\n",numPacket,dataLen);
while(numPacket-- > 0)
{
send(clifd,currData,sendLen,0); // send the nal data
currData += sendLen;
dataLen -= sendLen;
sendLen = dataLen;
if(sendLen > 16384)
sendLen = 16384;
}
}
else
{
// File read finished or get some error
break;
}
}
dataLen = 0;
send(clifd,&dataLen,4,0); // 通知client,文件读取结束
fclose(fin);
//fclose(fout);
close(clifd);
close(servfd);
return 0 ;
}
// --client端的代码
int main(int argc, char** argv)
{
int servfd,clifd,length = 0;
struct sockaddr_in servaddr,cliaddr;
socklen_t socklen = sizeof (servaddr);
char buf[BUFFER_SIZE];
int m = 0;
int t = 0;
FILE *fout = NULL;
int numPacket = 0;
int readLen = 0;
unsigned char *currData = NULL;
int curFlags = 0;
if (argc < 2 )
{
usage(argv[ 0 ]);
exit( 1 );
}
if ((clifd = socket(AF_INET,SOCK_STREAM, 0 )) < 0 )
{
printf( " create socket error!\n " );
exit( 1 );
}
srand(time(NULL)); // initialize random generator
memset( & cliaddr,0, sizeof (cliaddr));
cliaddr.sin_family = AF_INET;
cliaddr.sin_port = htons(CLIENT_PORT);
cliaddr.sin_addr.s_addr = htons(INADDR_ANY);
memset( & servaddr, 0,sizeof (servaddr));
servaddr.sin_family = AF_INET;
inet_aton(argv[ 1 ], & servaddr.sin_addr);
servaddr.sin_port = htons(SERVER_PORT);
if (bind(clifd, (struct sockaddr* ) &cliaddr, sizeof (cliaddr)) < 0 )
{
printf( " bind to port %d failure!\n " ,CLIENT_PORT);
exit( 1 );
}
if (connect(clifd,( struct sockaddr * ) & servaddr, socklen) < 0 )
{
printf( " can't connect to %s!\n ", argv[ 1 ]);
exit( 1 );
}
length = send(clifd,h264filename,strlen(h264filename), 0 );
if(length < 0)
{
printf("error when send file name to server\n");
exit(1);
}
while(1)
{
length = recv(clifd, &numPacket,4, 0);
printf("numPacket = %d ",numPacket);
if(numPacket == 0)
break;
currData = dataBuf;
length = 0;
while(numPacket-- > 0)
{
readLen = recv(clifd, currData,16384, 0);
length += readLen;
currData += readLen;
}
printf("dataLen=%d\n",length);
// do decode
}
close(clifd);
return 0;
}
7 个解决方案
#1
出了什么错?
调试能收数据,直接运行不行,这不太可能。
调试能收数据,直接运行不行,这不太可能。
#2
clifd = accept(servfd,( struct sockaddr * ) & cliaddr, & length);
char buf[255];
length = recv(clifd, buf, 255, 0);
前边检查的好好的,到这就不检查了。
char buf[255];
length = recv(clifd, buf, 255, 0);
前边检查的好好的,到这就不检查了。
#3
究竟出错的提示是什么
#4
没有提示,我打印了接收到数据包的长度,gdb的时候,和server端发送的每个包长度,以及numPacket的个数一致,但是直接run的时候,第一个packet的长度就不对了。
#5
用来测试的文件,发送的前面几个数据包的长度为:6389、134、138、138、138、144、144、36288。第一版的代码,我没有根据16K来拆分,除了最后一个包只接收到了16K,前面几个都正确。 所以我就增加了server端和client端基于16K的拆分循环。 结果run的时候,第一个包都接收不对了。跑了几次,还都很稳定,client打印的第一个包长度,只有2K多点。
#6
想不通,tcp编程还要拆包吗?
#7
开始没拆包,但是接收端没有接受正确,才认为的拆包的。
#1
出了什么错?
调试能收数据,直接运行不行,这不太可能。
调试能收数据,直接运行不行,这不太可能。
#2
clifd = accept(servfd,( struct sockaddr * ) & cliaddr, & length);
char buf[255];
length = recv(clifd, buf, 255, 0);
前边检查的好好的,到这就不检查了。
char buf[255];
length = recv(clifd, buf, 255, 0);
前边检查的好好的,到这就不检查了。
#3
究竟出错的提示是什么
#4
没有提示,我打印了接收到数据包的长度,gdb的时候,和server端发送的每个包长度,以及numPacket的个数一致,但是直接run的时候,第一个packet的长度就不对了。
#5
用来测试的文件,发送的前面几个数据包的长度为:6389、134、138、138、138、144、144、36288。第一版的代码,我没有根据16K来拆分,除了最后一个包只接收到了16K,前面几个都正确。 所以我就增加了server端和client端基于16K的拆分循环。 结果run的时候,第一个包都接收不对了。跑了几次,还都很稳定,client打印的第一个包长度,只有2K多点。
#6
想不通,tcp编程还要拆包吗?
#7
开始没拆包,但是接收端没有接受正确,才认为的拆包的。