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

写Socket Server 遇到一些小问题
不明白我的问题我在补充说明吧
下面是一小段伪代码
C/C++ code

sock = socket(AF_INET,SOCK_STREAM,0);
//设置套接口的选项 SO_REUSEADDR 允许在同一个端口启动服务器的多个实例
//setsockopt的第二个参数SOL SOCKET 指定系统中,解释选项的级别 普通套接字
setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,(char*)&optval,sizeof(optval));
bind(sock,(struct sockaddr *)&server_addr,sizeof(server_addr);
listen(sock,MAXCLINE);
while()
{
    select();//消除accept阻塞
    
    new_fd = accept(sock,(struct sockaddr *)&client_addr,&sin_size);

}


我想问setsockopt和ioctlsocket都是怎么用

C/C++ code

linger m_sLinger;
m_sLinger.l_onoff = 1;  // (在closesocket()调用,但是还有数据没发送完毕的时候容许逗留)
m_sLinger.l_linger = 0; // (容许逗留的时间为0秒)
if(setsockopt(sock,SOL_SOCKET,SO_LINGER,(const char*)&m_sLinger,sizeof(linger)) < 0)
//这样设置是不是就是closesocket时候直接就关闭了 没有逗留时间啊?

ioctlsocket ( sock,FIONBIO,&ch);   //这里设置非阻塞后下面的recv()也都是非阻塞了吗?
ioctlsocket ( sock,FIONREAD,&templen);   //这个也不懂参数是什么意思 msdn写的太不让人明白了



------解决方案--------------------
ioctlsocket ( sock,FIONREAD,&templen);
这个好像是得到socket缓冲区中的数据长度
------解决方案--------------------
FIONBIO 就是设置或取消“非阻塞”模式,如果第3个参数是非0,那就是设置
如果第3个参数是0,那就是取消
------解决方案--------------------
FIONBIO 设置后,就影响后面的recv send 阻塞与否了

FIONREAD 这个不是设置,是获取,获取socket缓冲区中的数据长度,也就是你随后调用recv将会读到的数据长度
------解决方案--------------------
setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,(char*)&optval,sizeof(optval))
设置端口重用,可以绑定在处于TIME_WAIT状态的端口。

ioctlsocket ( sock,FIONBIO,&ch); 
设置sock非阻塞,注意对一个监听套接字设置非阻塞,非阻塞标记并不会被accept得到的socket继承,一种办法是如下,另一种就是accept后再次设置新的套接字为非阻塞:
C/C++ code
       int accept4(int sockfd, struct sockaddr *addr,
                   socklen_t *addrlen, int flags);
       If flags is 0, then accept4() is the same as accept().  The following values can be bitwise ORed in flags to obtain different behavior:

       SOCK_NONBLOCK   Set the O_NONBLOCK file status flag on the new open file description.  Using this flag saves extra calls to fcntl(2) to achieve the same
                       result.