日期:2014-05-16  浏览次数:20829 次

非阻塞方式socket中, 去读select返回的sockfd是否一定是非0值??如果读到的字节数比期望少有没有什么好的处理模式??
非阻塞方式socket中,   去读select返回的sockfd是否一定是非0值??如果读到的字节数比期望少有没有什么好的处理模式??

1.非阻塞方式socket中,   如果去读select返回的sockfd返回是0,   是否一定代表对
    方关闭关闭了tcp连接??
2.如果读到的字节数比期望少有没有什么好的处理模式??   难道对每一个客户端
    socket都开一个缓冲区?   直到读完指定字节数后再去对此客户端做处理?


------解决方案--------------------
1 : see http://post.baidu.com/f?kz=94875093
------解决方案--------------------
tcp情况下,读sockfd后返回0,表示对方关闭连接,收到FIN
------解决方案--------------------
2 ssize_t /* Read "n " bytes from a descriptor. */
3 readn(int fd, void *vptr, size_t n)
4 {
5 size_t nleft;
6 ssize_t nread;
7 char *ptr;

8 ptr = vptr;
9 nleft = n;
10 while (nleft > 0) {
11 if ( (nread = read(fd, ptr, nleft)) < 0) {
12 if (errno == EINTR)
13 nread = 0; /* and call read() again */
14 else
15 return (-1);
16 } else if (nread == 0)
17 break; /* EOF */

18 nleft -= nread;
19 ptr += nread;
20 }
21 return (n - nleft); /* return > = 0 */
22 }


2 ssize_t /* Write "n " bytes to a descriptor. */
3 writen(int fd, const void *vptr, size_t n)
4 {
5 size_t nleft;
6 ssize_t nwritten;
7 const char *ptr;

8 ptr = vptr;
9 nleft = n;
10 while (nleft > 0) {
11 if ( (nwritten = write(fd, ptr, nleft)) <= 0) {
12 if (nwritten < 0 && errno == EINTR)
13 nwritten = 0; /* and call write() again */
14 else
15 return (-1); /* error */
16 }

17 nleft -= nwritten;
18 ptr += nwritten;
19 }
20 return (n);
21 }

------解决方案--------------------
1.说明是不可用的连接

2.这个要看你的业务要求吧
如果你要收一个结构体,当然要收取整个大小再处理
如果是收http的报文,因为不会有一个固定大小,边收边处理
------解决方案--------------------
为每一个连接保留一个缓冲,和位置指针, 读取时若发现数据不够,则更新位置指针,继续读
------解决方案--------------------
unp上有一个readn函数,它实现的是:
ssize_t /* Read "n " bytes from a descriptor. */
readn(int fd, void *vptr, size_t n)
{
size_t nleft;
ssize_t nread;
char *ptr;

ptr = vptr;
nleft = n;
while (nleft > 0) {
if ( (nread = read(fd, ptr, nleft)) < 0) {
if (errno == EINTR)
nread = 0; /* and call read() again */
else
return(-1);
} else if (nread == 0)
break; /* EOF */

nleft -= nread;
ptr += nread;
}
return(n - nleft); /* return > = 0 */
}
/* end readn */
但你要自己解决阻塞问题
------解决方案--------------------
在非阻塞socket中, 假设轮训(select,poll或epoll)后, 发现有10000个socket可读,
但读到的数据都少于期望值(也就是由于某种原因, 多个客户端发送过来的数据只过
来一部分,服务器一次没有读完全部数据)

难道要新开10000个缓冲区?? 并记住每个缓冲区的指针位置? 然后下一次在轮训再读??
如此循环往复直到读完为止??
--------------------------------------------
就是这样,10000比较夸张了。按每client 16K缓冲算也就160M的内存,对于要处理10000个client的机械来说不多呀。