今天只写一个问题。
tcp字节流接收问题,tcp是以流的形式发送到应用层的,比如1000个字节为单位,我们每次希望recv 1000个字节,但是它是以流的形式,也就是说也许这次只到了800个字节,因此我们只收到800个字节,那么下一次我们再去尝试读流中字节时,又到了1000个字节,怎么办呢? 会默认去把前面剩下的200个字节读完,然后读这一次的800个字节, 最后发现socket还可用 就继续读剩下的200 个字节。
1000 800 1000 200
1000。。1000。。1000。。
可以设一个标志位来让每次在读完了1000个字节后再进行某个操作。
/*监听服务器socket,是否有消息发来*/ int ret = select(sockfd+1,&grs_readset,NULL,NULL,grs_timeout); if (ret == -1) { break; }else if(ret == 0) { break; }else /*有消息发来*/ { if (FD_ISSET(sockfd,&grs_readset)) { if (!over_flag) { if ((recvbytes=recv(sockfd, (char *)resvmsg+totalbytes, sizeof(grs_session_info_c)-totalbytes,0)) ==-1) { perror("recv"); break; } totalbytes += recvbytes; }else if ((totalbytes=recv(sockfd, (char *)resvmsg, sizeof(grs_session_info_c),0)) ==-1) { perror("recv"); break; } GRUC_DBG("recvbytes = %d\r\n", recvbytes); if (totalbytes == sizeof(grs_session_info_c)) { over_flag = 1; totalbytes = 0; //notify GUI there is msg from server!
grs_session_info sinfo; sessionInfoC2Qt(*resvmsg,&sinfo); gpGuiCltObj->notifyRecvMsg(sinfo); }else if(totalbytes <= 0) { FD_CLR(sockfd,&allreadset); needStop = 1; //服务器断开连接,让客户端停止
break; }else { over_flag = 0; } FD_SET(sockfd,&allreadset); /*用allreadset保存,每次执行select会把以前的洗掉*/ } }
|
阅读(1836) | 评论(0) | 转发(0) |