socket异步处理问题

原创 2007年09月21日 08:48:00
由于一个项目要和第三方软件做接口,第三方软件是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;
        }
 

异步Socket接收数据后缓存处理问题

异步接收数据都正常,是个定长TLV包,但是接收到后都是直接写入bufflist后再getdata出来处理,发现有时会有掉包情况,以为是线程安全问题,后来加入了lock段将bufflist内代码锁住,依...
  • e_wsq
  • e_wsq
  • 2013年10月16日 02:13
  • 2077

Android多线程及异步处理问题

本文出自:http://myqdroid.blog.51cto.com/2057579/392157 1、问题提出 1)为何需要多线程? 2)多线程如何实现? 3)多线程机制的核心是啥? 4...

Android多线程及异步处理问题详细探讨

究其为啥需要多线程的本质就是异步处理,直观一点说就是不要让用户感觉到“很卡”为了提高用户体验那是必须要使用的 1、问题提出  1)为何需要多线程?  2)多线程如何实现?  3)多线程机制...

Java socket 分析3---Socket异常处理问题

第1个异常是 java.net.BindException:Address already in use: JVM_Bind。 该异常发生在服务器端进行new ServerSocket(port)(...
  • fclwd
  • fclwd
  • 2013年03月31日 02:50
  • 610

欧姆龙指令的时间处理问题

  • 2015年03月31日 16:29
  • 368KB
  • 下载

CXF-JAXB包的处理问题

  • 2014年11月06日 10:46
  • 76KB
  • 下载

处理问题:变量名‘@UserName’已声明。变量名在插叙批次或存储过程内部必须唯一

在做.net版机房收费系统时,遇到这样一个问题:登陆系统时,在B层的登陆函数UserLogin_BLL()中调用了D层的两个函数—判断用户是否存在IsUserExist_DA(),验证密码是否正确Ch...

C# 导入文件时字符集的处理问题

  • 2013年08月22日 11:08
  • 31KB
  • 下载

opencv SVM处理问题实例讲解

  • 2014年07月15日 20:39
  • 473KB
  • 下载

Netty5用户手册之五:netty中流数据的传输处理问题

在如tcp/ip的以流为基础传输数据中,数据被接收后,被保存在一个socket接收缓冲区中。不幸的是,这个以流为基础的缓冲区buffer不是一个包packet的队列,而是一个字节byte队列。这意味着...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:socket异步处理问题
举报原因:
原因补充:

(最多只允许输入30个字)