using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.IO; using System.Threading; using System.Net; using System.Net.Sockets; namespace TestServer { class Program { static List<ServerPlayer> playerList = new List<ServerPlayer>(); static void Main(string[] args) { TcpListener server=null; try { Int32 port = 13000; IPAddress localAddr = IPAddress.Parse("127.0.0.1"); server = new TcpListener(localAddr, port); server.Start(); Console.WriteLine("Server started"); while(true) { Console.Write("Waiting for a connection... "); TcpClient client = server.AcceptTcpClient(); Console.WriteLine("Connected!"); playerList.Add( new ServerPlayer(client) ); ThreadPoolInfo(); } } catch(SocketException e) { Console.WriteLine("SocketException: {0}", e); } finally { server.Stop(); } Console.WriteLine("\nHit enter to continue..."); Console.Read(); } //显示线程池现状 static void ThreadPoolInfo() { int a, b; ThreadPool.GetAvailableThreads(out a, out b); string message = string.Format("CurrentThreadId is : {0}\n" + "WorkerThreads is : {1}\nCompletionPortThreads is : {2}\n", Thread.CurrentThread.ManagedThreadId, a.ToString(), b.ToString()); Console.WriteLine(message); } } } public class ServerPlayer { private TcpClient tcpClient; private byte[] receiveBuffer; private string clientEndPoint; public ServerPlayer(TcpClient tcpClient) { this.tcpClient = tcpClient; receiveBuffer = new byte[tcpClient.ReceiveBufferSize]; //显示客户端信息 clientEndPoint = tcpClient.Client.RemoteEndPoint.ToString(); Console.WriteLine("Client connected : " + clientEndPoint); NetworkStream stream = tcpClient.GetStream(); stream.BeginRead(receiveBuffer, 0, receiveBuffer.Length, new AsyncCallback(ReadCallback), stream); } void ReadCallback(IAsyncResult result) { NetworkStream stream = (NetworkStream)result.AsyncState; int length = stream.EndRead(result); if (length < 1)//TCP中断了 { Console.WriteLine("client disconnected : " + clientEndPoint); return; } //显示接收信息 string message = Encoding.UTF8.GetString(receiveBuffer, 0, length); Console.WriteLine("Message: " + message); //向客户端返回ok byte[] msg = System.Text.Encoding.UTF8.GetBytes("ok"); stream.Write(msg, 0, msg.Length); stream.BeginRead(receiveBuffer, 0, receiveBuffer.Length, new AsyncCallback(ReadCallback), stream); } }
运行效果
示例二:增加大厅功能,实现聊天室
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.IO; using System.Threading; using System.Net; using System.Net.Sockets; namespace TestServer { class Program { static ServerLobby defaultLobby; static void Main(string[] args) { TcpListener server = null; try { Int32 port = 13000; IPAddress localAddr = IPAddress.Parse("127.0.0.1"); server = new TcpListener(localAddr, port); server.Start(); Console.WriteLine("Server started"); //建立默认大厅 defaultLobby = new ServerLobby(); while (true) { Console.WriteLine("Waiting for a connection... "); TcpClient client = server.AcceptTcpClient(); Console.WriteLine("Connected!"); //进入大厅 ServerPlayer player = new ServerPlayer(client); defaultLobby.OnEnterServerPlayer(player); ThreadPoolInfo(); } } catch (SocketException e) { Console.WriteLine("SocketException: {0}", e); } finally { server.Stop(); } Console.WriteLine("\nHit enter to continue..."); Console.Read(); } //显示线程池现状 static void ThreadPoolInfo() { int a, b; ThreadPool.GetAvailableThreads(out a, out b); string message = string.Format("CurrentThreadId is : {0}\n" + "WorkerThreads is : {1}\nCompletionPortThreads is : {2}\n", Thread.CurrentThread.ManagedThreadId, a.ToString(), b.ToString()); Console.WriteLine(message); } } } // 大厅,管理所有ServerPlayer public class ServerLobby { private List<ServerPlayer> playerList = new List<ServerPlayer>(); // 有玩家进入大厅 public void OnEnterServerPlayer(ServerPlayer player) { player.OnEnterLobby(this); playerList.Add(player); } // 有玩家离开大厅 public void OnLeaveServerPlayer(ServerPlayer player) { playerList.Remove(player); player.OnLeaveLobby(); } // 向大厅中的所有玩家广播消息 public void BroadcastMessage(string msg) { for (int i=0; i<playerList.Count; i++) { if (playerList[i] == null) continue; playerList[i].SendMessage(msg); } } } public class ServerPlayer { private TcpClient tcpClient; private NetworkStream stream; private byte[] receiveBuffer; private string clientEndPoint; private AsyncCallback mAsyncCallback; private ServerLobby mServerLobby; private string clientIP; public string IP { get { return clientIP; } } public ServerPlayer(TcpClient tcpClient) { this.tcpClient = tcpClient; receiveBuffer = new byte[tcpClient.ReceiveBufferSize]; //显示客户端信息 clientEndPoint = tcpClient.Client.RemoteEndPoint.ToString(); clientIP = clientEndPoint; Console.WriteLine("Client connected : " + clientEndPoint); stream = tcpClient.GetStream(); mAsyncCallback = new AsyncCallback(ReadCallback); stream.BeginRead(receiveBuffer, 0, receiveBuffer.Length, mAsyncCallback, stream); } void ReadCallback(IAsyncResult result) { NetworkStream stream = (NetworkStream)result.AsyncState; int length = stream.EndRead(result); if (length < 1)//TCP中断了 { Console.WriteLine("client disconnected : " + clientEndPoint); //离开大厅 if (mServerLobby != null) mServerLobby.OnLeaveServerPlayer(this); return; } //显示接收信息 string message = Encoding.UTF8.GetString(receiveBuffer, 0, length); Console.WriteLine("Message: " + message); //向大厅中的所有玩家同步消息 mServerLobby.BroadcastMessage("sync: " + message.Trim() + "\r\n"); stream.BeginRead(receiveBuffer, 0, receiveBuffer.Length, mAsyncCallback, stream); } // 发消息 public void SendMessage(string msg) { if (!tcpClient.Connected) return; byte[] bytes = System.Text.Encoding.UTF8.GetBytes(msg); stream.Write(bytes, 0, msg.Length); } // 本玩家进入大厅触发 public void OnEnterLobby(ServerLobby lobby) { mServerLobby = lobby; //通知大厅中的其他玩家 mServerLobby.BroadcastMessage(IP + " enter lobby\r\n"); } // 本玩家离开大厅触发 public void OnLeaveLobby() { //通知大厅中的其他玩家 mServerLobby.BroadcastMessage(IP + " leave lobby\r\n"); mServerLobby = null; } }
运行测试