TCP/IP
send recv read write数据收发不完整
解决方法:
write和send
1.write和send的返回值是读到的字节数。在send和write端检查send的返回值,若正确则发送,否则重发,send错误时返回-1,另一方使用正常方式关闭时返回0
2.write不负责把数据写完再返回
read和recv
1.read和recv返回值为读到的字节数。如果read和recv的返回值为0表示读到了末尾,也就是接收到EOF(end of file),返回-1时错误,可通过errno获取错误码
TCP/IP收发正确,但是缓冲区数据不更新
解决方法:
使用select去检查缓冲区的数据,如果有数据则读取(也就是清空),如果为空则跳过。把阻塞方式变成非阻塞
//示例代码
while(1)
{
/*receive datas from client*/
if((recvSize=recv(clientfd,recvBuf,MAX_DATA_SIZE,0))==-1)
{
perror("fail to receive datas");
exit(1);
}
printf("%s\n",recvBuf);
memset(recvBuf,0,MAX_DATA_SIZE);
/*send datas to client*/
printf("Server:");
fgets(sendBuf,MAX_DATA_SIZE,stdin);
if((sendSize=send(clientfd,sendBuf,strlen(sendBuf),0))!=strlen(sendBuf))
{
perror("fail to send datas");
exit(1);
}
printf("Success to send datas\n");
memset(sendBuf,0,MAX_DATA_SIZE);
}
完整读取所有内容的read代码
int my_read(int fd,void *buffer,int length)
{
int bytes_left;
int bytes_read;
char *ptr;
bytes_left=length;
while(bytes_left>0)
{
bytes_read = read(fd,ptr,bytes_read);
if (bytes_read < 0)
{
if(errno==EINTR)
bytes_read=0;
else
return(-1);
}
else if(bytes_read==0)
break;
bytes_left-=bytes_read;
ptr+=bytes_read;
}
return(length-bytes_left);
}
完整写入所有内容的write代码
int my_write(int fd,void *buffer,int length)
{
int bytes_left;
int written_bytes;
char *ptr;
ptr=buffer;
bytes_left=length;
while(bytes_left>0)
{
/* 开始写*/
written_bytes=write(fd,ptr,bytes_left);
if(written_bytes<=0) /* 出错了*/
{
if(errno==EINTR) /* 中断错误我们继续写*/
written_bytes=0;
else /* 其他错误没有办法,只好撤退了*/
return(-1);
}
bytes_left-=written_bytes;
ptr+=written_bytes; /* 从剩下的地方继续写 */
}
return(0);
}