CSharp之传奇3网关-LoginGate

由于CSharp提供很好Socket封装的类,所以写起来也很方便~~~

监听TcpListener ServerSocket;
与LoginSvr之间的通讯TcpClient ClientSocket;

其实,很多朋友在这里,都会觉得在这一方面很困惑,觉得没有像Delphi有控件。其实,CSharp更简单。

public   void  StartServer()
{
    
//  创建一个监听本地7000端口的ServerSocket对象
    ServerSocket  =   new  TcpListener( 5500 );
    
//  开始监听本地7000端口
   ServerSocket.Start();
}

以上代码,就实现了对本地7000端口的的监听,是不是很简单呢?下面来讲如何监听有客户端访问。

public   void  StartServer()
{
    
//  创建一个监听本地7000端口的ServerSocket对象
    ServerSocket  =   new  TcpListener( 5500 );
    
//  开始监听本地7000端口
    ServerSocket.Start();
    
//  异步监听客户端访问,其实这里相当于新启动了一个进程。
    ServerSocket.BeginAcceptTcpClient( new  AsyncCallback(ComplageAcceptTcpClient),  null );
}

private   void  ComplageAcceptTcpClient(IAsyncResult ar)
{
    
//  监听是否有客户端传入,相当于Console.Read()一样。接收到有传入,就把传入的信息赋予Client。
    TcpClient Client  =  ServerSocket.EndAcceptTcpClient(ar);
}

这面就实现了对客户的监听,是不是很简单呢?下面来谈谈收到用户信息后如果处理。在DELPHI里,用了一个Timer对UserSession进行遍历然后发送。这里,其实也可以,不过既然有这么好的封装,何不创建一个Session的对象呢?

ContractedBlock.gif ExpandedBlockStart.gif 创建一个Session的类
public class TUserSession
ExpandedBlockStart.gifContractedBlock.gif
{
    
// 远端信息
ExpandedSubBlockStart.gifContractedSubBlock.gif
    public TcpClient Client getset; }
    
// 是否连接
ExpandedSubBlockStart.gifContractedSubBlock.gif
    public bool IsConnected getset; }
    
// 开始连接的时间
ExpandedSubBlockStart.gifContractedSubBlock.gif
    public int ConnectTick getset;}

    
// 缓冲区大小,也就是接收信息的最大字节数
    private const int BufferSize = 4096;
    
// 缓冲区
    private byte[] _buffer = new byte[BufferSize];

    
// Socket发送与接收的一个流
    private NetworkStream _streamToClient;

    
// 开始监听客户端传来的信息
    public void BeginRead()
ExpandedSubBlockStart.gifContractedSubBlock.gif    
{
        
if(Client != null)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            
// 获取Client的流(简化了很多代码)
        _streamToClient = Client.GetStream();
            
// 看到了吧,这里又用到异步了,启动监听。
            _streamToClient.BeginRead(_buffer, BufferSize, new AsyncCallback(ComplateRead), null);
        }

    }


    
private void ComplateRead(IAsyncResult ar)
ExpandedSubBlockStart.gifContractedSubBlock.gif    
{
        
int bytesRead;
        
try
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            
// 程序到这里会阻断,直到客户端发送数据。
            bytesRead = _streamToClient.EndRead(ar);
            
if(bytesRead > 0)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                
// 将接收到的信息转为字符
                string RecviceText = Encoding.Default.GetString(_buffer, 0, bytesRead);

                对这条接收到的信息怎么处理,就可以在这里实现了。

           
// 继续监听客户端,只要客户端没有断开或服务断开客户端的连接,这里就成了无限的循环了
           
// 因为bytesRead = _streamToClient.EndRead(ar);是阻断模式,所以不用担心会出现程序崩溃。
           _streamToClient.BeginRead(_buffer, BufferSize, new AsyncCallback(ComplateRead), null);
            }

            
else
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                
// 如果客户端关闭或断开连接,就会发送一个0字节的流,所以这里要断开连接
                if(_streamToClient != null)
                    _streamToClient.Dispose();
                
if(Client != null)
                    Client.Close();
                
this.IsConnected = false;
            }

        }

        
catch(SocketExcept ex)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
        }

    }


    
// 向客户端发送一条消息
    public void SendText(string text)
ExpandedSubBlockStart.gifContractedSubBlock.gif    
{
        
if(this.IsConnected)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            
byte[] sendBuffer = Encoding.Default.GetBytes(text);
            _streamToClient.Send(sendBuffer, 
0, sendBuffer.Length);
        }

    }

}


public List<TUserSession> UserSession = new List<TUserSession>();

这样,就OK了。是不是很简单?

ContractedBlock.gif ExpandedBlockStart.gif 开始监听是否有客户端传入
private void ComplageAcceptTcpClient(IAsyncResult ar)
ExpandedBlockStart.gifContractedBlock.gif
{
    
// 监听是否有客户端传入,相当于Console.Read()一样。接收到有传入,就把传入的信息赋予Client。
    TcpClient Client = ServerSocket.EndAcceptTcpClient(ar);

    在这里可以加入一些过滤,比如连接IP数据是不是太多?是不是永久过滤的吖?如果是,直接Client.Close()掉就可以啦。

    
// 当接到到一个客户端,就new一个Session对象
    TUserSession userSession = new TUserSession();
    userSession.Client 
= Client;
    userSession.IsConnected 
= true;
    userSession.ConnectTick 
= Environment.TickCount;
    userSession.BeginRead();
    UserSession.Add(userSession);

    
// 最后别忘了加这一条,叫他无限循环。由于是阻断模式,所以到TcpClient Client = ServerSocket.EndAcceptTcpClient(ar);这里会停下,直到有新的客户端进来。
    ServerSocket.BeginAcceptTcpClient(new AsyncCallback(ComplageAcceptTcpClient), null);
}

这样,就完成了打开7000端口并监听客户端,是不是很简单呢?

个人博客:星烁小屋(http://www.zks.cn/)

引用:http://www.zks.cn/article.asp?id=45

posted on 2008-11-18 14:56 星之烁 阅读( ...) 评论( ...) 编辑 收藏

转载于:https://www.cnblogs.com/wkavenger/archive/2008/11/18/1335961.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值