C# 套接字的select选择模型

75 篇文章 2 订阅
51 篇文章 0 订阅

 select选择模型是套接字进行异步IO的基本模式,非常方便。

在C++中,select()函数的原型如下:

int select(
  __in          int nfds,
  __in_out      fd_set* readfds,
  __in_out      fd_set* writefds,
  __in_out      fd_set* exceptfds,
  __in          const struct timeval* timeout
);

即,使用fd_set结构体来存放读、写、异常状况的套接字;

使用宏FD_ZEOR来清空fd_set集、FD_SET来增加套接字到某个fd_set集中、FD_CLR来删除某个fd_set集中的套接字、FD_ISSET来判断套接字是否属于某个fd_set集;

timeout参数使用INFINITE可一直等待,直到函数放回(有套接字满足条件)

返回值是原fd_set集经过select()函数筛选之后的满足条件(即有读、写或异常状态)套接字的数量,然后依次进行I/O操作;

在C#中,select方法内化为Socket类的静态方法之一,fd_set也用更为方便的ArrayList类来代替(该类实现了IList接口)

select方法的原型如下:

public static void Select(
	IList checkRead,
	IList checkWrite,
	IList checkError,
	int microSeconds
)

当microSeconds=-1时,表示一直等待,直到套接字满足条件后返回

可以看到,该函数没有返回值。因为满足需要的套接字都留在了ArrayList类的对象中,用ArrayList对象的count属性判断个数,以数组下标形式逐个访问套接字以进行I/O操作即可。

下面是MSDN中给出的一个示例(有改动):

//获取主机IP
IPHostEntry ipHostEntry = Dns.Resolve(Dns.GetHostName());
IPAddress ipAddress = ipHostEntry.AddressList[0];

Socket socket0 = null;
Socket socket1 = null; 
Socket socket2 = null; 
Socket remoteSock = null; 


//存放监听套接字
ArrayList listenList = new ArrayList();
listenList.Add(socket0);
listenList.Add(socket1);
listenList.Add(socket2);

//创建3个TCP监听套接字
for( int i = 0; i < 3; i++ )
{
    listenList[i] = new Socket(AddressFamily.InterNetwork,
                             SocketType.Stream,
                             ProtocolType.Tcp);
    //注意类型转换
    ((Socket)listenList[i]).Bind(new IPEndPoint(ipAddress, 11000 + i));
    ((Socket)listenList[i]).Listen(10);
}

// Only the sockets that contain a connection request
// will remain in listenList after Select returns.

Socket.Select(listenList, null, null, 1000);

for( int i = 0; i < listenList.Count; i++ )
{
    acceptList[i] = ((Socket)listenList[i]).Accept();
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值