socket异步处理问题
生活随笔
收集整理的這篇文章主要介紹了
socket异步处理问题
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
由于一個項目要和第三方軟件做接口,第三方軟件是Unix的操作系統,所以用了Socket來傳輸數據。
具體結構是這樣的:本項目作為服務器端,第三方軟件是客戶端,并且有多個客戶端。
通常情況下,要開多個線程來處理多個客戶端,并且一個客戶端要占用一個端口,每個客戶端在訪問服務端時,服務器端要找到當前空閑的端口返回給客戶端進行調用。
msdn上提供了這種的解決方案:
http://www.microsoft.com/china/msdn/archives/library/dncscol/html/csharp09182003.asp
但是,經過我今天的摸索,發現用socket異步處理也能解決這個問題,只要一個端口就可以給n個客戶端訪問了。
并且客戶不需要做異步處理,只是服務端做異步處理就可以了。這樣的話,第三方軟件改動量就很小,主要控制權在我這里。
客戶端做法的代碼片斷:
創建連接:
mobj_stSend?=?new?Socket?(?AddressFamily.InterNetwork?,?
????????????????????SocketType.Stream?,?ProtocolType.Tcp?)?;?//初始化一個Socket實例?
????????????????
????????????????IPEndPoint?tempRemoteIP?=?new?IPEndPoint?
????????????????????(?IPAddress.Parse?(?textBox1.Text?)?,?mi_port?)?;?//根據IP地址和端口號創建遠程終結點?
????????????????
????????????????EndPoint?epTemp?=?(?EndPoint?)?tempRemoteIP?;?
????????????????mobj_stSend.Connect?(?epTemp?)?;?//連接遠程主機的8000端口號?
發送數據:
?int?iLength?=?textBox2.Text.Length?;?//獲取要發送的數據的長度?
????????????
????????????????Byte?[?]?bySend?=?new?byte?[?iLength?]?;?//根據獲取的長度定義一個Byte類型數組?
????????????
????????????????bySend?=?System.Text.Encoding.Default.GetBytes?
????????????????????(?textBox2.Text?)?;?//按照指定編碼類型把字符串指定到指定的Byte數組?
????????????
????????????????int?i?=?mobj_stSend.Send?(?bySend?)?;?//發送數據?
服務器端做了一個Socket數組來存放所有客戶端的連接: private?Socket?ListenSoc?;?
????????public?static?ManualResetEvent?allDone?=?new?ManualResetEvent(false);
????????private?Socket?[]?SocClient;
????????private?const?int?MAX_SOCKET=?100;
????????Thread?mobj_thTreadRead;
啟動監聽線程:
?
mobj_thTreadRead?=?new?Thread?(?new?ThreadStart?(?Listen?)?)?;//以Listen過程來初始化Thread實例????????????
????????????mobj_thTreadRead.Start()?;//啟動線程????????????
????????????button1.Enabled?=?false??;
在Listen方法中使用異步訪問:
void?Listen()
????????{
????????????int?nPort?=?8000;????????????
????????????IPEndPoint?ipLocalEndPoint;
????????????try
????????????{
//????????????????IPAddress?ipAddress?=?Dns.Resolve("localhost").AddressList[0];
????????????????ipLocalEndPoint?=?new?IPEndPoint(GetServerIP(),?nPort);?
????????????}
????????????catch(SocketException?socErr?)
????????????{
????????????????MessageBox.Show(socErr.Message);
????????????????return;
????????????}
???????????
????????????try
????????????{????????????????
????????????????ListenSoc?=?new?Socket(AddressFamily.InterNetwork,?SocketType.Stream,ProtocolType.Tcp?);
????????????????ListenSoc.Bind(ipLocalEndPoint);
????????????????ListenSoc.Listen(100);
????????????????while?(true)
????????????????{
????????????????????allDone.Reset();
????????????????????ListenSoc.Soc.BeginAccept(new?AsyncCallback(AcceptCallback),ListenSoc); //異步訪問,并定義回調方法
????????????????????allDone.WaitOne();
????????????????}
????????????}
????????????catch(Exception?err)?
????????????{
????????????????MessageBox.Show(err.Message);
????????????}
????????}
實現回調方法:
public?void?AcceptCallback(IAsyncResult?ar)?
????????{
????????????try
????????????{
????????????????allDone.Set();
????????????????WSocket?listener?=?(WSocket)?ar.AsyncState;
????????????????int?nSoc?=?GetAvailbleSocket();?//獲取有效的Socket,即一個新的Socket實例
SocClient[nSoc]?=?(Socket)ListenSoc.EndAccept(ar);
//在這里處理接收過來得數據
}
}
private?int?GetAvailbleSocket()
????????{
????????????int?i=-1;
????????????for(?i=0;i<MAX_SOCKET;i++)
????????????{
????????????????try
????????????????{
????????????????????if?(SocClient[i]==null)
????????????????????????break;
????????????????????else
????????????????????{
????????????????????????if?(!SocClient[i].Soc.Connected)
????????????????????????????break;
????????????????????}
????????????????}
????????????????catch?(Exception?err)?
????????????????{
????????????????????MessageBox.Show("GetSock?:"+err.Message);
????????????????}
????????????}
????????????if?((i>-1)&&?(i?<MAX_SOCKET))??
????????????????InitSocket(ref?SocClient[i],i);
????????????return?i;
????????} ?
具體結構是這樣的:本項目作為服務器端,第三方軟件是客戶端,并且有多個客戶端。
通常情況下,要開多個線程來處理多個客戶端,并且一個客戶端要占用一個端口,每個客戶端在訪問服務端時,服務器端要找到當前空閑的端口返回給客戶端進行調用。
msdn上提供了這種的解決方案:
http://www.microsoft.com/china/msdn/archives/library/dncscol/html/csharp09182003.asp
但是,經過我今天的摸索,發現用socket異步處理也能解決這個問題,只要一個端口就可以給n個客戶端訪問了。
并且客戶不需要做異步處理,只是服務端做異步處理就可以了。這樣的話,第三方軟件改動量就很小,主要控制權在我這里。
客戶端做法的代碼片斷:
創建連接:
mobj_stSend?=?new?Socket?(?AddressFamily.InterNetwork?,?
????????????????????SocketType.Stream?,?ProtocolType.Tcp?)?;?//初始化一個Socket實例?
????????????????
????????????????IPEndPoint?tempRemoteIP?=?new?IPEndPoint?
????????????????????(?IPAddress.Parse?(?textBox1.Text?)?,?mi_port?)?;?//根據IP地址和端口號創建遠程終結點?
????????????????
????????????????EndPoint?epTemp?=?(?EndPoint?)?tempRemoteIP?;?
????????????????mobj_stSend.Connect?(?epTemp?)?;?//連接遠程主機的8000端口號?
發送數據:
?int?iLength?=?textBox2.Text.Length?;?//獲取要發送的數據的長度?
????????????
????????????????Byte?[?]?bySend?=?new?byte?[?iLength?]?;?//根據獲取的長度定義一個Byte類型數組?
????????????
????????????????bySend?=?System.Text.Encoding.Default.GetBytes?
????????????????????(?textBox2.Text?)?;?//按照指定編碼類型把字符串指定到指定的Byte數組?
????????????
????????????????int?i?=?mobj_stSend.Send?(?bySend?)?;?//發送數據?
服務器端做了一個Socket數組來存放所有客戶端的連接: private?Socket?ListenSoc?;?
????????public?static?ManualResetEvent?allDone?=?new?ManualResetEvent(false);
????????private?Socket?[]?SocClient;
????????private?const?int?MAX_SOCKET=?100;
????????Thread?mobj_thTreadRead;
啟動監聽線程:
?
mobj_thTreadRead?=?new?Thread?(?new?ThreadStart?(?Listen?)?)?;//以Listen過程來初始化Thread實例????????????
????????????mobj_thTreadRead.Start()?;//啟動線程????????????
????????????button1.Enabled?=?false??;
在Listen方法中使用異步訪問:
void?Listen()
????????{
????????????int?nPort?=?8000;????????????
????????????IPEndPoint?ipLocalEndPoint;
????????????try
????????????{
//????????????????IPAddress?ipAddress?=?Dns.Resolve("localhost").AddressList[0];
????????????????ipLocalEndPoint?=?new?IPEndPoint(GetServerIP(),?nPort);?
????????????}
????????????catch(SocketException?socErr?)
????????????{
????????????????MessageBox.Show(socErr.Message);
????????????????return;
????????????}
???????????
????????????try
????????????{????????????????
????????????????ListenSoc?=?new?Socket(AddressFamily.InterNetwork,?SocketType.Stream,ProtocolType.Tcp?);
????????????????ListenSoc.Bind(ipLocalEndPoint);
????????????????ListenSoc.Listen(100);
????????????????while?(true)
????????????????{
????????????????????allDone.Reset();
????????????????????ListenSoc.Soc.BeginAccept(new?AsyncCallback(AcceptCallback),ListenSoc); //異步訪問,并定義回調方法
????????????????????allDone.WaitOne();
????????????????}
????????????}
????????????catch(Exception?err)?
????????????{
????????????????MessageBox.Show(err.Message);
????????????}
????????}
實現回調方法:
public?void?AcceptCallback(IAsyncResult?ar)?
????????{
????????????try
????????????{
????????????????allDone.Set();
????????????????WSocket?listener?=?(WSocket)?ar.AsyncState;
????????????????int?nSoc?=?GetAvailbleSocket();?//獲取有效的Socket,即一個新的Socket實例
SocClient[nSoc]?=?(Socket)ListenSoc.EndAccept(ar);
//在這里處理接收過來得數據
}
}
private?int?GetAvailbleSocket()
????????{
????????????int?i=-1;
????????????for(?i=0;i<MAX_SOCKET;i++)
????????????{
????????????????try
????????????????{
????????????????????if?(SocClient[i]==null)
????????????????????????break;
????????????????????else
????????????????????{
????????????????????????if?(!SocClient[i].Soc.Connected)
????????????????????????????break;
????????????????????}
????????????????}
????????????????catch?(Exception?err)?
????????????????{
????????????????????MessageBox.Show("GetSock?:"+err.Message);
????????????????}
????????????}
????????????if?((i>-1)&&?(i?<MAX_SOCKET))??
????????????????InitSocket(ref?SocClient[i],i);
????????????return?i;
????????} ?
轉載于:https://www.cnblogs.com/duadu/archive/2007/09/21/6167035.html
總結
以上是生活随笔為你收集整理的socket异步处理问题的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 2021年中国研究生数学建模竞赛E题参考
- 下一篇: 搭建PyQt环境(Vs Code)