首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 操作系统 > UNIXLINUX >

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

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

非阻塞方式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_tnleft;
ssize_tnread;
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的机械来说不多呀。

[解决办法]
1, yes
2, buffer

对于第二个问题,除了缓存起来,别无它发。要么用阻塞模式,你不做就得kernel做,活儿总的有人干。
[解决办法]
执行成功则返回文件描述词状态已改变的个数,如果返回0代表在描述词状态改变前已超过timeout时间,当有错误发生时则返回-1,错误原因存于errno

热点排行