基于linux的简单socket编程,gdb时,可以正确传输数据,直接run,会出错。

时间:2021-09-22 04:41:35
各位,
    目的是在一个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);

前边检查的好好的,到这就不检查了。

#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


引用 5 楼  的回复:
用来测试的文件,发送的前面几个数据包的长度为:6389、134、138、138、138、144、144、36288。第一版的代码,我没有根据16K来拆分,除了最后一个包只接收到了16K,前面几个都正确。 所以我就增加了server端和client端基于16K的拆分循环。 结果run的时候,第一个包都接收不对了。跑了几次,还都很稳定,client打印的第一个包长度,只有2K多点。

想不通,tcp编程还要拆包吗?

#7


开始没拆包,但是接收端没有接受正确,才认为的拆包的。

#1


出了什么错?

调试能收数据,直接运行不行,这不太可能。

#2


    clifd  =  accept(servfd,( struct  sockaddr * ) & cliaddr, & length);
    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


引用 5 楼  的回复:
用来测试的文件,发送的前面几个数据包的长度为:6389、134、138、138、138、144、144、36288。第一版的代码,我没有根据16K来拆分,除了最后一个包只接收到了16K,前面几个都正确。 所以我就增加了server端和client端基于16K的拆分循环。 结果run的时候,第一个包都接收不对了。跑了几次,还都很稳定,client打印的第一个包长度,只有2K多点。

想不通,tcp编程还要拆包吗?

#7


开始没拆包,但是接收端没有接受正确,才认为的拆包的。