C#Socket 網路通訊非同步處理 SocketAsyncEventArgs 非同步通訊端操作
1.服務端簡單實現:
Code:
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.用戶端簡單實現:
Code:
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)); } } }