C# 同步/异步即时通信/聊天 源代码
一、同步聊天
服务器端:
using System; using System.Net; using System.Net.Sockets; using System.Text; public class SynchronousSocketServer { // 接收到的客户端的消息. public static string data = null; public static void StartListening() { // 接收缓冲. byte[] bytes; // 通过DNS获得本地的 Endpoint //IPHostEntry ipHostInfo = Dns.GetHostEntry(Dns.GetHostName()); //IPAddress ipAddress = ipHostInfo.AddressList[0]; //IPEndPoint localEndPoint = new IPEndPoint(ipAddress, 11000); IPEndPoint localEndPoint = new IPEndPoint(IPAddress.Loopback, 11000); // 建立 TCP/IP socket. Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); // 绑定 socket 的本地地址 // 监听连接申请. try { listener.Bind(localEndPoint); listener.Listen(10); // 监听连接申请. while (true) { Console.WriteLine("等待连接 ..."); // 程序被阻塞,等待用户连接 Socket handler = listener.Accept(); data = null; // 处理用户的连接. while (true) { bytes = new byte[1024]; int bytesRec = handler.Receive(bytes); data = Encoding.Default.GetString(bytes, 0, bytesRec); Console.WriteLine("{0}: {1}", handler.RemoteEndPoint, data); if (data.ToUpper() == "EXIT") break; } //// Show the data on the console. //Console.WriteLine("Text received : {0}", data); // Echo the data back to the client. byte[] msg = Encoding.Default.GetBytes("连接已断开."); handler.Send(msg); handler.Shutdown(SocketShutdown.Both); handler.Close(); } } catch (Exception e) { Console.WriteLine(e.ToString()); } Console.WriteLine("\n按 ENTER 键继续 ..."); Console.Read(); } public static int Main(String[] args) { StartListening(); return 0; } }
客户端:
using System; using System.Net; using System.Net.Sockets; using System.Text; public class SynchronousSocketClient { public static void StartClient() { // 接收缓冲. byte[] bytes = new byte[1024]; string str = null; // 链接到远程服务器. try { // 建立远程 Endpoint . //IPEndPoint remoteEP = new IPEndPoint(IPAddress.Parse(args[0]), 11000); IPEndPoint remoteEP = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 11000); // 建立 TCP/IP socket. Socket sender = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); // 连接到 remote endpoint try { sender.Connect(remoteEP); Console.WriteLine("已连接到 {0}\n请输入聊天信息: ", sender.RemoteEndPoint.ToString()); while (true) { str = Console.ReadLine(); // 编码. byte[] msg = Encoding.Default.GetBytes(str); // 发送消息. int bytesSent = sender.Send(msg); if (str.ToUpper() == "EXIT") break; } // 接收响应. int bytesRec = sender.Receive(bytes); Console.WriteLine("接收到: {0}", Encoding.Default.GetString(bytes, 0, bytesRec)); // 关闭 socket. sender.Shutdown(SocketShutdown.Both); sender.Close(); Console.ReadKey(); } catch (ArgumentNullException ane) { Console.WriteLine("ArgumentNullException : {0}", ane.ToString()); } catch (SocketException se) { Console.WriteLine("SocketException : {0}", se.ToString()); } catch (Exception e) { Console.WriteLine("Unexpected exception : {0}", e.ToString()); } } catch (Exception e) { Console.WriteLine(e.ToString()); } } public static int Main(String[] args) { StartClient(); return 0; } }
二、异步聊天
服务器端:
using System; using System.Net; using System.Net.Sockets; using System.Text; using System.Threading; // StateObject 用于保存异步读取的客户端数据 public class StateObject { // 客户端 socket. public Socket workSocket = null; // 接收缓冲的大小. public const int BufferSize = 1024; // 接收缓冲. public byte[] buffer = new byte[BufferSize]; // 接收到的消息. public StringBuilder sb = new StringBuilder(); } public class AsynchronousSocketListener { // 线程信号. public static ManualResetEvent allDone = new ManualResetEvent(false); public AsynchronousSocketListener() { } public static void StartListening() { // 输入缓冲. byte[] bytes = new Byte[1024]; // 建立本地 Endpoint . //IPHostEntry ipHostInfo = Dns.GetHostEntry(Dns.GetHostName()); //IPAddress ipAddress = ipHostInfo.AddressList[0]; //IPEndPoint localEndPoint = new IPEndPoint(ipAddress, 11000); IPEndPoint localEndPoint = new IPEndPoint(IPAddress.Loopback, 11000); // 建立 TCP/IP socket. Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); // 绑定本地 endpoint 并 监听进入的连接. try { listener.Bind(localEndPoint); listener.Listen(100); while (true) { // 重置事件的 无信号 状态. allDone.Reset(); // 启动异步 socket 来监听连接. Console.WriteLine("等待连接 ..."); listener.BeginAccept( new AsyncCallback(AcceptCallback), listener); // 等待,只到连接被建立. allDone.WaitOne(); } } catch (Exception e) { Console.WriteLine(e.ToString()); } Console.WriteLine("\n按 ENTER 键继续 ..."); Console.Read(); } public static void AcceptCallback(IAsyncResult ar) { // 发信号让主线程继续. allDone.Set(); // 获取客户连接. Socket listener = (Socket)ar.AsyncState; Socket handler = listener.EndAccept(ar); // 建立 state object. StateObject state = new StateObject(); state.workSocket = handler; handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallback), state); } public static void ReadCallback(IAsyncResult ar) { String content = String.Empty; // 恢复 state object 和 socket. StateObject state = (StateObject)ar.AsyncState; Socket handler = state.workSocket; // 从客户 socket 读取消息. int bytesRead = handler.EndReceive(ar); if (bytesRead > 0) { // 存储收到的消息. state.sb.Append(Encoding.Default.GetString( state.buffer, 0, bytesRead)); // 检查结束标记. content = state.sb.ToString(); if (content.IndexOf("<EOF>") > -1) { // 显示获得的客户端的所有信息. Console.WriteLine("从 {0} 获得了 {1} 个字符: {2}", state.workSocket.RemoteEndPoint, content.Length, content); // 将信息回送给客户端. Send(handler, content); } else { // 未接收到结束标记. 继续接收. handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallback), state); } } } private static void Send(Socket handler, String data) { // 将消息转换成字节流. byte[] byteData = Encoding.Default.GetBytes(data); // 送数据到客户端. handler.BeginSend(byteData, 0, byteData.Length, 0, new AsyncCallback(SendCallback), handler); } private static void SendCallback(IAsyncResult ar) { try { // 从 state object 恢复 Socket. Socket handler = (Socket)ar.AsyncState; // 发送数据. int bytesSent = handler.EndSend(ar); Console.WriteLine("发送 {0} 个字符给 {1}.", bytesSent, handler.RemoteEndPoint); handler.Shutdown(SocketShutdown.Both); handler.Close(); } catch (Exception e) { Console.WriteLine(e.ToString()); } } public static int Main(String[] args) { StartListening(); return 0; } }
客户端:
using System; using System.Net; using System.Net.Sockets; using System.Threading; using System.Text; // State object 保存从远程端收到的消息. public class StateObject { // 客户 socket. public Socket workSocket = null; // 接收缓冲的大小. public const int BufferSize = 256; // 接收缓冲. public byte[] buffer = new byte[BufferSize]; // 收到的消息. public StringBuilder sb = new StringBuilder(); } public class AsynchronousClient { // 远程端口号. private const int port = 11000; // 手工结束事件的信号. private static ManualResetEvent connectDone = new ManualResetEvent(false); private static ManualResetEvent sendDone = new ManualResetEvent(false); private static ManualResetEvent receiveDone = new ManualResetEvent(false); // 远程设备的响应. private static String response = String.Empty; private static void StartClient() { // 建立连接. try { // 建立连接的远端 endpoint . IPHostEntry ipHostInfo = Dns.GetHostEntry("127.0.0.1"); IPAddress ipAddress = ipHostInfo.AddressList[0]; IPEndPoint remoteEP = new IPEndPoint(ipAddress, port); // 建立 TCP/IP socket. Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); // 连接到远端 endpoint . client.BeginConnect(remoteEP, new AsyncCallback(ConnectCallback), client); connectDone.WaitOne(); // 送测试数据到远端. Send(client, "测试数据 <EOF>"); sendDone.WaitOne(); // 接收远端发回的消息. Receive(client); receiveDone.WaitOne(); // 输出远端发回的消息. Console.WriteLine("收到的响应 : {0}", response); // 释放 socket. client.Shutdown(SocketShutdown.Both); client.Close(); } catch (Exception e) { Console.WriteLine(e.ToString()); } } private static void ConnectCallback(IAsyncResult ar) { try { // 从 state object 中恢复 socket . Socket client = (Socket)ar.AsyncState; // 完成连接. client.EndConnect(ar); Console.WriteLine("Socket 连接到 {0}", client.RemoteEndPoint.ToString()); // 发链接已建立的信号. connectDone.Set(); } catch (Exception e) { Console.WriteLine(e.ToString()); } } private static void Receive(Socket client) { try { // 建立 state object. StateObject state = new StateObject(); state.workSocket = client; // 开始从远端接收消息. client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReceiveCallback), state); } catch (Exception e) { Console.WriteLine(e.ToString()); } } private static void ReceiveCallback(IAsyncResult ar) { try { // 恢复 state object 和远程 socket StateObject state = (StateObject)ar.AsyncState; Socket client = state.workSocket; // 从远端接收消息. int bytesRead = client.EndReceive(ar); if (bytesRead > 0) { // 读取数据. state.sb.Append(Encoding.Default.GetString(state.buffer, 0, bytesRead)); // 继续读剩下的数据. client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReceiveCallback), state); } else { // 当数据全部到达后; 发回响应. if (state.sb.Length > 1) { response = state.sb.ToString(); } // 发出收到所有消息的信号. receiveDone.Set(); } } catch (Exception e) { Console.WriteLine(e.ToString()); } } private static void Send(Socket client, String data) { // 编码字符串. byte[] byteData = Encoding.Default.GetBytes(data); // 开始送数据到客户端. client.BeginSend(byteData, 0, byteData.Length, 0, new AsyncCallback(SendCallback), client); } private static void SendCallback(IAsyncResult ar) { try { // 从 state object 中恢复 socket . Socket client = (Socket)ar.AsyncState; // 完成数据的发送. int bytesSent = client.EndSend(ar); Console.WriteLine("送 {0} 个字符到服务器.", bytesSent); // 发数据已发送的信号. sendDone.Set(); } catch (Exception e) { Console.WriteLine(e.ToString()); } } public static int Main(String[] args) { StartClient(); return 0; } }
浙公网安备 33010602011771号