`

socket异步处理问题

 
阅读更多
<iframe align="top" marginwidth="0" marginheight="0" src="http://www.zealware.com/46860.html" frameborder="0" width="468" scrolling="no" height="60"></iframe>
由于一个项目要和第三方软件做接口,第三方软件是Unix的操作系统,所以用了Socket来传输数据。
具体结构是这样的:本项目作为服务器端,第三方软件是客户端,并且有多个客户端。

通常情况下,要开多个线程来处理多个客户端,并且一个客户端要占用一个端口,每个客户端在访问服务端时,服务器端要找到当前空闲的端口返回给客户端进行调用。
msdn上提供了这种的解决方案:
http://www.microsoft.com/china/msdn/archives/library/dncscol/html/csharp09182003.asp

但是,经过我今天的摸索,发现用socket异步处理也能解决这个问题,只要一个端口就可以给n个客户端访问了。
并且客户不需要做异步处理,只是服务端做异步处理就可以了。这样的话,第三方软件改动量就很小,主要控制权在我这里。
客户端做法的代码片断:
创建连接:
mobj_stSend=newSocket(AddressFamily.InterNetwork,
SocketType.Stream,ProtocolType.Tcp);
//初始化一个Socket实例

IPEndPointtempRemoteIP
=newIPEndPoint
(IPAddress.Parse(textBox1.Text),mi_port);
//根据IP地址和端口号创建远程终结点

EndPointepTemp
=(EndPoint)tempRemoteIP;
mobj_stSend.Connect(epTemp);
//连接远程主机的8000端口号

发送数据:
intiLength=textBox2.Text.Length;//获取要发送的数据的长度

Byte[]bySend
=newbyte[iLength];//根据获取的长度定义一个Byte类型数组

bySend
=System.Text.Encoding.Default.GetBytes
(textBox2.Text);
//按照指定编码类型把字符串指定到指定的Byte数组

inti=mobj_stSend.Send(bySend);//发送数据

服务器端做了一个Socket数组来存放所有客户端的连接:
privateSocketListenSoc;
publicstaticManualResetEventallDone=newManualResetEvent(false);
privateSocket[]SocClient;
privateconstintMAX_SOCKET=100;
Threadmobj_thTreadRead;

启动监听线程:

mobj_thTreadRead=newThread(newThreadStart(Listen));//以Listen过程来初始化Thread实例
mobj_thTreadRead.Start();//启动线程
button1.Enabled=false;

在Listen方法中使用异步访问:
voidListen()
{
intnPort=8000;
IPEndPointipLocalEndPoint;
try
{
//IPAddressipAddress=Dns.Resolve("localhost").AddressList[0];
ipLocalEndPoint=newIPEndPoint(GetServerIP(),nPort);
}

catch(SocketExceptionsocErr)
{
MessageBox.Show(socErr.Message);
return;
}


try
{
ListenSoc
=newSocket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
ListenSoc.Bind(ipLocalEndPoint);
ListenSoc.Listen(
100);
while(true)
{
allDone.Reset();
ListenSoc.Soc.BeginAccept(
newAsyncCallback(AcceptCallback),ListenSoc); //异步访问,并定义回调方法
allDone.WaitOne();

}

}

catch(Exceptionerr)
{
MessageBox.Show(err.Message);
}

}

实现回调方法:
publicvoidAcceptCallback(IAsyncResultar)
{
try
{
allDone.Set();
WSocketlistener
=(WSocket)ar.AsyncState;
intnSoc=GetAvailbleSocket();//获取有效的Socket,即一个新的Socket实例
SocClient[nSoc]=(Socket)ListenSoc.EndAccept(ar);
//在这里处理接收过来得数据
}

}

privateintGetAvailbleSocket()
{
inti=-1;
for(i=0;iMAX_SOCKET;i++)
{
try
{
if(SocClient[i]==null)
break;
else
{
if(!SocClient[i].Soc.Connected)
break;
}

}

catch(Exceptionerr)
{
MessageBox.Show(
"GetSock:"+err.Message);
}


}


if((i>-1)&&(iMAX_SOCKET))
InitSocket(
refSocClient[i],i);
returni;
}


Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=1793977


分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics