C#Socket 網路通信非同步處理 SocketAsyncEventArgs 非同步套接字操作 1.服務端簡單實現: 2.客戶端簡單實現: ...
C#Socket 網路通信非同步處理 SocketAsyncEventArgs 非同步套接字操作
1.服務端簡單實現:
public partial class Form_Server : Form { private Socket socket; public Form_Server() { InitializeComponent(); } private void Form_Server_Load(object sender, EventArgs e) { try { //獲取本地ip地址 IPAddress ipaddress = Dns.GetHostByName(Dns.GetHostName()).AddressList[0]; txt_ip.Text = ipaddress.ToString(); } catch (Exception ex) { MessageBox.Show(ex.Message); } } //開啟Socket監聽 private void btn_listent_open_Click(object sender, EventArgs e) { try { if (string.IsNullOrEmpty(txt_ip.Text)) { MessageBox.Show("請輸入IP地址"); } //打開監聽 IPAddress ip = IPAddress.Parse(txt_ip.Text); IPEndPoint localEP = new IPEndPoint(ip, Int32.Parse(txt_port.Text)); socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); socket.Bind(localEP); socket.Listen(1000); //AcceptAsync非同步方式 SocketAsyncEventArgs socketAsyncEventArgs = new SocketAsyncEventArgs(); socketAsyncEventArgs.Completed += new EventHandler<SocketAsyncEventArgs>(socketAsyncEventArgs_Completed_AcceptAsync); socketAsyncEventArgs.RemoteEndPoint = localEP; socketAsyncEventArgs.UserToken = socket; socket.AcceptAsync(socketAsyncEventArgs); //消息提示 this.lb_msg.Items.Add("[服務端]:"); this.lb_msg.Items.Add(" 監聽成功"); } catch (Exception ex) { MessageBox.Show(ex.Message); } } //開始一個非同步操作來接受一個傳入的連接嘗試 void socketAsyncEventArgs_Completed_AcceptAsync(object ServerSocket, SocketAsyncEventArgs e) { //已關閉,重疊的操作被中止 if (e.SocketError == SocketError.OperationAborted) { //已關閉,重疊的操作被中止 this.lb_msg.Invoke(new Action(() => { this.lb_msg.Items.Add("[服戶端]:"); this.lb_msg.Items.Add(" socketAsyncEventArgs_Completed_AcceptAsync:已關閉,重疊的操作被中止>SocketError:OperationAborted"); })); return; } //此連接由遠程對等電腦重置 if (e.SocketError == SocketError.ConnectionReset && e.BytesTransferred == 0) { //此連接由遠程對等電腦重置 this.lb_msg.Invoke(new Action(() => { this.lb_msg.Items.Add("[服戶端]:"); this.lb_msg.Items.Add(" socketAsyncEventArgs_Completed_AcceptAsync:此連接由遠程對等電腦重置>SocketError:ConnectionReset"); })); return; } if (e.LastOperation == SocketAsyncOperation.Accept) { try { Socket acceptSocket = e.AcceptSocket; //開始一個非同步請求以便從連接的 System.Net.Sockets.Socket 對象中接收數據 SocketAsyncEventArgs socketAsyncEventArgsReceiveAsync = new SocketAsyncEventArgs(); socketAsyncEventArgsReceiveAsync.UserToken = acceptSocket; byte[] receiveBuff = new byte[1024 * 4]; socketAsyncEventArgsReceiveAsync.SetBuffer(receiveBuff, 0, receiveBuff.Length); socketAsyncEventArgsReceiveAsync.Completed += new EventHandler<SocketAsyncEventArgs>(socketAsyncEventArgs_Completed_ReceiveAsync); acceptSocket.ReceiveAsync(socketAsyncEventArgsReceiveAsync); //消息提示 this.lb_msg.Invoke(new Action(() => { this.lb_msg.Items.Add("[客戶端]:"); this.lb_msg.Items.Add(" 連接成功"); })); } catch (Exception ex) { MessageBox.Show(ex.Message); } //開始一個非同步操作來接受一個傳入的連接嘗試,遞歸 e.AcceptSocket = null; socket.AcceptAsync(e); } } //開始一個非同步請求以便從連接的 System.Net.Sockets.Socket 對象中接收數據 void socketAsyncEventArgs_Completed_ReceiveAsync(object acceptSocket, SocketAsyncEventArgs e) { //已關閉,重疊的操作被中止 if (e.SocketError == SocketError.OperationAborted) { //已關閉,重疊的操作被中止 this.lb_msg.Invoke(new Action(() => { this.lb_msg.Items.Add("[服戶端]:"); this.lb_msg.Items.Add(" socketAsyncEventArgs_Completed_ReceiveAsync:已關閉,重疊的操作被中止>SocketError:OperationAborted"); })); return; } //此連接由遠程對等電腦重置 if (e.SocketError == SocketError.ConnectionReset && e.BytesTransferred == 0) { //此連接由遠程對等電腦重置 this.lb_msg.Invoke(new Action(() => { this.lb_msg.Items.Add("[服戶端]:"); this.lb_msg.Items.Add(" socketAsyncEventArgs_Completed_ReceiveAsync:此連接由遠程對等電腦重置>SocketError:ConnectionReset"); })); return; } if (e.SocketError == SocketError.Success && e.Buffer.Length > 0) { try { Socket socket = acceptSocket as Socket; string ipAddress = socket.RemoteEndPoint.ToString(); int lengthuffer = e.BytesTransferred; byte[] receiveBuffer = e.Buffer; byte[] buffer = new byte[lengthuffer]; Buffer.BlockCopy(receiveBuffer, 0, buffer, 0, lengthuffer); string message = Encoding.UTF8.GetString(buffer); this.lb_msg.Invoke(new Action(() => { this.lb_msg.Items.Add("[客戶端]:"); this.lb_msg.Items.Add(" " + message); })); socket.Send(Encoding.UTF8.GetBytes(string.Format("收到消息{0}:{1}", DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss"), message))); socket.ReceiveAsync(e); } catch (Exception ex) { MessageBox.Show(ex.Message); } } } //關閉Socket監聽 private void btn_listent_Close_Click(object sender, EventArgs e) { try { if (socket != null) { socket.Close(); } this.lb_msg.Items.Add("[服務端]:"); this.lb_msg.Items.Add(" 關閉監聽成功"); } catch (Exception ex) { MessageBox.Show(ex.Message); } } }
2.客戶端簡單實現:
public partial class ClientMainForm : Form { private Socket _socket; public ClientMainForm() { InitializeComponent(); } //登錄 private void btn_login_Click(object sender, EventArgs e) { try { IPAddress ip = IPAddress.Parse(this.txt_ip.Text); IPEndPoint ipendPoint = new IPEndPoint(ip, Int32.Parse(this.txt_port.Text)); _socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); _socket.Connect(ipendPoint); this.lb_msg.Items.Add("[客戶端]:"); this.lb_msg.Items.Add(" 連接服務端成功"); //開啟新的接受消息非同步操作事件 SocketAsyncEventArgs socketAsyncEventArgs = new SocketAsyncEventArgs(); //設置消息的緩衝區大小 byte[] receiveBuff = new byte[1024 * 4]; socketAsyncEventArgs.SetBuffer(receiveBuff, 0, receiveBuff.Length); socketAsyncEventArgs.UserToken = _socket; //綁定回調事件 socketAsyncEventArgs.Completed += socketAsyncEventArgs_Completed_ReceiveAsync; _socket.ReceiveAsync(socketAsyncEventArgs); } catch (Exception ex) { MessageBox.Show(ex.Message); } } //開始一個非同步請求以便從連接的 System.Net.Sockets.Socket 對象中接收數據。 void socketAsyncEventArgs_Completed_ReceiveAsync(object sender, SocketAsyncEventArgs e) { //已關閉,重疊的操作被中止 if (e.SocketError == SocketError.OperationAborted) { this.lb_msg.Invoke(new Action(() => { this.lb_msg.Items.Add("[客戶端]:"); this.lb_msg.Items.Add(" socketAsyncEventArgs_Completed_ReceiveAsync:已關閉,重疊的操作被中止:OperationAborted"); })); return; } //此連接由遠程對等電腦重置 if (e.SocketError == SocketError.ConnectionReset && e.BytesTransferred == 0) { //此連接由遠程對等電腦重置 this.lb_msg.Invoke(new Action(() => { this.lb_msg.Items.Add("[客戶端]:"); this.lb_msg.Items.Add(" socketAsyncEventArgs_Completed_ReceiveAsync:此連接由遠程對等電腦重置:ConnectionReset"); })); return; } Socket socket = sender as Socket; if(e.SocketError==SocketError.Success&&e.Buffer.Length>0) { string ipAddress = socket.RemoteEndPoint.ToString(); int lengthuffer = e.BytesTransferred; byte[] receiveBuffer = e.Buffer; byte[] buffer = new byte[lengthuffer]; Buffer.BlockCopy(receiveBuffer, 0, buffer, 0, lengthuffer); string message = Encoding.UTF8.GetString(buffer); this.lb_msg.Invoke(new Action(() => { this.lb_msg.Items.Add("[服務戶端]:"); this.lb_msg.Items.Add(" " + message); })); socket.ReceiveAsync(e); } } //發送消息 private void btn_sendmsg_Click(object sender, EventArgs e) { if (string.IsNullOrEmpty(txt_msg.Text)) { MessageBox.Show("請輸入消息"); } else { _socket.Send(System.Text.Encoding.UTF8.GetBytes(txt_msg.Text)); } } }