异步Socket的聊天程序
来源:互联网 发布:武汉编程培训机构 编辑:程序博客网 时间:2024/04/28 18:41
Socket网络应用程序如同一般文件I/O一样在数据存取未完成的时候,整个应用程序会停滞,直到网络操作完全成功为止。若是遇上不佳的网络环境,这种情形将会严重影响整个网络程序的运作。对于网络延迟,.NET提供了自己的一组解决方法,异步操作。
Socket类提供的方法成员中包含一组专门用来进行异步操作的Socket方法。这些方法以成对出现:BeginConnect 与 EndConnect 提供异步联机功能、BeginAccept 与 EndAccept 提供异步接受请求、 BeginReceive与 EndReceive 异步接收数据、BeginSend与EndSend 异步发送数据。
其实这些方法和同步相当类似,最大的差异在于AsyncCallback类派生对象,上述的异步方法接受一个AsyncCallback对象,封装回调方法,并在Socket网络操作完成之后,返回IAsyncResult接口对象。此对象被当作参数。传入回调的方法,回调的方法调用结束相关异步方法,并且传入IAsyncResult,取得相关的异步操作信息。
服务端代码示例
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Net;using System.Net.Sockets;using System.Threading;namespace AsyncSocketServer{ class Program { const string strSuffix = "$";//定义结尾 Thread newThread;//开启线程 static Socket socket; static int port = 8003;//定义侦听端口 //允许线程通过发信号互相通信。通常,此通信涉及一个线程在其他线程进行之前必须完成的任务。 public static ManualResetEvent manualResetEvent = new ManualResetEvent(false);//线程通过发信号互相通信,通知一个或多个正在等待的线程已发生事件 private const int MAX_SOCKET = 10; /// <summary> /// 服务器端 /// </summary> /// <param name="args"></param> static void Main(string[] args) { Thread newThread = new Thread(new ThreadStart(BebinListen)); newThread.Start(); } /// <summary> /// 获取服务器地址 /// </summary> /// <returns></returns> private static IPAddress GetServerIp() { IPHostEntry iPHostEntry = Dns.GetHostEntry(Dns.GetHostName()); return iPHostEntry.AddressList[0]; } //异步传递的状态对象 public class StateOject { public Socket workSocket = null; public const int BufferSize = 1024; public byte[] buffer = new byte[BufferSize]; public StringBuilder stringBuilder = new StringBuilder(); } /// <summary> /// 开始监听 /// </summary> private static void BebinListen() { //定义监听 socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); IPAddress ServerIp = GetServerIp(); IPEndPoint ipEndPoint = new IPEndPoint(ServerIp, port); socket.Bind(ipEndPoint); Console.WriteLine(ipEndPoint.ToString() + "正在监听..."); socket.Listen(5); //接收消息 byte[] byteMessage = new byte[100]; while (true) { try { manualResetEvent.Reset(); manualResetEvent.WaitOne(); } catch (Exception exception) { } } } /// <summary> /// 异步接收回调函数 /// </summary> /// <param name="iAsyncResult"></param> private void AcceptCallback(IAsyncResult iAsyncResult) { Socket listener = (Socket)iAsyncResult.AsyncState; Socket client = listener.EndAccept(iAsyncResult); manualResetEvent.Set(); //StateObject:一个用户定义对象,其中包含接收操作的相关信息。当操作完成时, //此对象会被传递给EndReceive 委托。 StateOject state = new StateOject(); state.workSocket = client; //远端信息 EndPoint tempRemoteEP = client.RemoteEndPoint; IPEndPoint tempRemoteIP = (IPEndPoint)tempRemoteEP; string rempIp = tempRemoteIP.Address.ToString(); string rempPort = tempRemoteIP.Port.ToString(); IPHostEntry host = Dns.GetHostEntry(tempRemoteIP.Address); string hostName = host.HostName; string msg = "接受[" + hostName + "]" + rempIp + ":"+rempPort+"远程计算机连接!"; Console.WriteLine(msg.ToString()+"\r\n"); client.BeginReceive(state.buffer, 0, StateOject.BufferSize, 0, new AsyncCallback(SendCallback), state); } /// <summary> /// 异步接收回调函数 /// </summary> /// <param name="iAsyncResult"></param> private void readCallback(IAsyncResult iAsyncResult) { StateOject state = (StateOject)iAsyncResult.AsyncState; Socket handler = state.workSocket; int bytesRead = handler.EndReceive(iAsyncResult); if (bytesRead > 0) { string msg = Encoding.Default.GetString(state.buffer, 0, bytesRead); state.stringBuilder.Append(msg); string content = state.stringBuilder.ToString(); EndPoint tempRemoteEP = handler.RemoteEndPoint; IPEndPoint tempRemoteIp = (IPEndPoint)tempRemoteEP; string rempIp = tempRemoteIp.Address.ToString(); string rempPort = tempRemoteIp.Port.ToString(); IPHostEntry host = Dns.GetHostEntry(tempRemoteIp.Address); string hostName = host.HostName; string strMsg = "(" + DateTime.Now.ToString() + ")接收来自" + hostName + ":"; strMsg += DelStrSuffix(strMsg); Console.WriteLine(strMsg.ToString()); } } /// <summary> /// 异步发送回调函数 /// </summary> /// <param name="iAsyncResult"></param> private void SendCallback(IAsyncResult iAsyncResult) { try { Socket handler = (Socket)iAsyncResult.AsyncState; int bytesSent = handler.EndSend(iAsyncResult); handler.Shutdown(SocketShutdown.Both); handler.Close(); } catch (SocketException socketException) { Console.WriteLine(socketException.ToString()); } } /// <summary> /// 异步发送 /// </summary> /// <param name="handleer"></param> /// <param name="data"></param> private void Send(Socket handler, string data) { byte[] byteDate = Encoding.Default.GetBytes(data + strSuffix); handler.Send(byteDate); } /// <summary> /// 去除字符串结尾的特殊字符 /// </summary> /// <param name="strContent"></param> /// <returns></returns> private string DelStrSuffix(string strContent) { int ed = strContent.LastIndexOf(strSuffix); string content = strContent.Remove(ed); return content; } }}客户端代码示例
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Net;using System.Net.Sockets;namespace AsyncSocketClient{ class Program { const string strSuffix = "$"; static Socket socket; int numbyte = 1024;//一次接收到的字节数。 int port=8003; /// <summary> /// 客户端 /// </summary> /// <param name="args"></param> static void Main(string[] args) { SnedMessage(); } /// <summary> /// 获取本机IP地址 /// </summary> /// <returns></returns> private static IPAddress GetClientIp() { IPHostEntry ipHostEntry = Dns.GetHostEntry(Dns.GetHostName()); return ipHostEntry.AddressList[0]; } //发送信息 private static void SnedMessage() { try { socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); IPAddress serverIp=GetClientIp(); int serverPort = 8003; IPEndPoint remoteIep = new IPEndPoint(serverIp, serverPort); socket.Connect(remoteIep); IPEndPoint tempLocalPoint = (IPEndPoint)socket.LocalEndPoint; string msg= "端口:" + tempLocalPoint.Port.ToString() + "正在监听......"; } catch { Console.WriteLine( "无法连接到目标计算机!"); return; } try { Console.WriteLine( "正在发送信息!"); string message ="this is test example!!!!!"; SendInfo(message); } catch //异常处理 { Console.WriteLine("无法发送信息到目标计算机!"); } } //发送信息 private static void SendInfo(string message) { byte[] byteMessage = Encoding.Default.GetBytes(message + strSuffix); socket.Send(byteMessage); //远端信息 EndPoint tempRemoteEP = socket.RemoteEndPoint; IPEndPoint tempRemoteIP = (IPEndPoint)tempRemoteEP; string rempip = tempRemoteIP.Address.ToString(); string remoport = tempRemoteIP.Port.ToString(); IPHostEntry host = Dns.GetHostEntry(tempRemoteIP.Address); string HostName = host.HostName; //发送信息 string time1 = DateTime.Now.ToString(); //发送完了,直接接收 StringBuilder sb = new StringBuilder(); while (true) { Console.WriteLine("正在等待接收信息..."); byte[] bytes = new byte[1000]; int recvbytes = socket.Receive(bytes); string strmsg = Encoding.Default.GetString(bytes); sb.Append(strmsg); if (sb.ToString().IndexOf(strSuffix) > -1) { break; } } Console.WriteLine("接收信息完毕!"); //代码解码,对返回的信息进行处理 socket.Shutdown(SocketShutdown.Both); socket.Close(); } //去除字符串结尾特殊符号 private string DelStrSuffix(string strcontent) { int ed = strcontent.LastIndexOf(strSuffix); string content = strcontent.Remove(ed); return content; } }}
- 异步Socket的聊天程序
- 异步Socket写聊天程序
- 异步Socket写聊天程序
- Linux下socket异步通讯聊天程序
- Linux下socket异步通讯聊天程序
- Linux下socket异步通讯聊天程序(转)
- WINDOWS平台下的SOCKET聊天程序
- 简单的Socket聊天程序(客户端)
- 小小的java socket聊天程序
- 基于Socket简单的聊天程序
- 一个简单的socket通信聊天程序
- Socket编程 一个小的聊天程序
- 非常简单的Socket聊天程序
- Win32API 写的 Socket 聊天小程序
- 一个简易的聊天程序(Socket)
- Scala编写的简单Socket聊天程序
- 结合多线程、Socket的聊天小程序
- 一个简单的局域网Socket聊天程序
- MFC实现打开、保存文件对话框和浏览文件夹对话框
- 采用Spring来实现定时器
- 【linux】gawk 的关联数组
- FLEX学习笔记:Canvas的填充特性——不填充相当于没有
- Alert Dialog "Done"按钮定义.
- 异步Socket的聊天程序
- MFC U盘检测
- 如何获取单元格内容
- 水浒:All Men Are Brothers
- Set in Java Collection
- 如何解决TIME_WAIT过多的解决办法(附Socket中的TIME_WAIT状态详解)
- MessageBox 和AfxMessageBox函数的区别
- ABAP:List中回写CheckBox的值到内表
- 创业之法