由于CSharp提供很好Socket封装的类,所以写起来也很方便~~~
监听TcpListener ServerSocket;
与LoginSvr之间的通讯TcpClient ClientSocket;
其实,很多朋友在这里,都会觉得在这一方面很困惑,觉得没有像Delphi有控件。其实,CSharp更简单。
public
void
StartServer()
{
// 创建一个监听本地7000端口的ServerSocket对象
ServerSocket = new TcpListener( 5500 );
// 开始监听本地7000端口
ServerSocket.Start();
}
{
// 创建一个监听本地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);
}
{
// 创建一个监听本地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的对象呢?
创建一个Session的类
public class TUserSession
{
// 远端信息
public TcpClient Client { get; set; }
// 是否连接
public bool IsConnected { get; set; }
// 开始连接的时间
public int ConnectTick { get; set;}
// 缓冲区大小,也就是接收信息的最大字节数
private const int BufferSize = 4096;
// 缓冲区
private byte[] _buffer = new byte[BufferSize];
// Socket发送与接收的一个流
private NetworkStream _streamToClient;
// 开始监听客户端传来的信息
public void BeginRead()
{
if(Client != null)
{
// 获取Client的流(简化了很多代码)
_streamToClient = Client.GetStream();
// 看到了吧,这里又用到异步了,启动监听。
_streamToClient.BeginRead(_buffer, BufferSize, new AsyncCallback(ComplateRead), null);
}
}
private void ComplateRead(IAsyncResult ar)
{
int bytesRead;
try
{
// 程序到这里会阻断,直到客户端发送数据。
bytesRead = _streamToClient.EndRead(ar);
if(bytesRead > 0)
{
// 将接收到的信息转为字符
string RecviceText = Encoding.Default.GetString(_buffer, 0, bytesRead);
对这条接收到的信息怎么处理,就可以在这里实现了。
// 继续监听客户端,只要客户端没有断开或服务断开客户端的连接,这里就成了无限的循环了
// 因为bytesRead = _streamToClient.EndRead(ar);是阻断模式,所以不用担心会出现程序崩溃。
_streamToClient.BeginRead(_buffer, BufferSize, new AsyncCallback(ComplateRead), null);
}
else
{
// 如果客户端关闭或断开连接,就会发送一个0字节的流,所以这里要断开连接
if(_streamToClient != null)
_streamToClient.Dispose();
if(Client != null)
Client.Close();
this.IsConnected = false;
}
}
catch(SocketExcept ex)
{
}
}
// 向客户端发送一条消息
public void SendText(string text)
{
if(this.IsConnected)
{
byte[] sendBuffer = Encoding.Default.GetBytes(text);
_streamToClient.Send(sendBuffer, 0, sendBuffer.Length);
}
}
}
public List<TUserSession> UserSession = new List<TUserSession>();
public class TUserSession
{
// 远端信息
public TcpClient Client { get; set; }
// 是否连接
public bool IsConnected { get; set; }
// 开始连接的时间
public int ConnectTick { get; set;}
// 缓冲区大小,也就是接收信息的最大字节数
private const int BufferSize = 4096;
// 缓冲区
private byte[] _buffer = new byte[BufferSize];
// Socket发送与接收的一个流
private NetworkStream _streamToClient;
// 开始监听客户端传来的信息
public void BeginRead()
{
if(Client != null)
{
// 获取Client的流(简化了很多代码)
_streamToClient = Client.GetStream();
// 看到了吧,这里又用到异步了,启动监听。
_streamToClient.BeginRead(_buffer, BufferSize, new AsyncCallback(ComplateRead), null);
}
}
private void ComplateRead(IAsyncResult ar)
{
int bytesRead;
try
{
// 程序到这里会阻断,直到客户端发送数据。
bytesRead = _streamToClient.EndRead(ar);
if(bytesRead > 0)
{
// 将接收到的信息转为字符
string RecviceText = Encoding.Default.GetString(_buffer, 0, bytesRead);
对这条接收到的信息怎么处理,就可以在这里实现了。
// 继续监听客户端,只要客户端没有断开或服务断开客户端的连接,这里就成了无限的循环了
// 因为bytesRead = _streamToClient.EndRead(ar);是阻断模式,所以不用担心会出现程序崩溃。
_streamToClient.BeginRead(_buffer, BufferSize, new AsyncCallback(ComplateRead), null);
}
else
{
// 如果客户端关闭或断开连接,就会发送一个0字节的流,所以这里要断开连接
if(_streamToClient != null)
_streamToClient.Dispose();
if(Client != null)
Client.Close();
this.IsConnected = false;
}
}
catch(SocketExcept ex)
{
}
}
// 向客户端发送一条消息
public void SendText(string text)
{
if(this.IsConnected)
{
byte[] sendBuffer = Encoding.Default.GetBytes(text);
_streamToClient.Send(sendBuffer, 0, sendBuffer.Length);
}
}
}
public List<TUserSession> UserSession = new List<TUserSession>();
这样,就OK了。是不是很简单?
开始监听是否有客户端传入
private void ComplageAcceptTcpClient(IAsyncResult ar)
{
// 监听是否有客户端传入,相当于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);
}
private void ComplageAcceptTcpClient(IAsyncResult ar)
{
// 监听是否有客户端传入,相当于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/)