socket通信
socket通信的时候一般就是连接,连接之后进行发送接收等等操作。
现在我来说说同步通信和异步通信的区别
很简单的,如果我们将通信比作计时多个运动员跑步,同步通信就相当于每个运动元都得配一个人计时的。异步通信就是一个人可以记录多个运动员跑步。
socket通信----同步通信
同步通信
client.connetction();
client.send();
client.receive();
socket通信----异步通信
异步通信
这里面主要是在连接,发送,接收的时候有了AsyncCallback异步回调机制
客户端
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Net; using System.Net.Sockets; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; namespace socketClient { public partial class Client : Form { private static ManualResetEvent connectDone = new ManualResetEvent(false); public Client() { InitializeComponent(); } private void textLog_TextChanged(object sender, EventArgs e) { } private static ManualResetEvent sendDone = new ManualResetEvent(false); private static ManualResetEvent receiveDone = new ManualResetEvent(false); private static String response = String.Empty; Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); private void btn_Connect_Click_Click(object sender, EventArgs e) { //连接到的目标ip IPAddress ip = IPAddress.Parse(textIP.Text); //连接到目标IP的哪个应用(端口号!) IPEndPoint point = new IPEndPoint(ip, int.Parse(textPort.Text)); //try //{ // //连接到服务器 // client.Connect(point); // ShowMsg("连接成功"); // ShowMsg("服务器" + client.RemoteEndPoint.ToString()); // ShowMsg("客户端:" + client.LocalEndPoint.ToString()); //Control.CheckForIllegalCrossThreadCalls = false; //消除跨线程 // //连接成功后,就可以接收服务器发送的信息了 //Thread th = new Thread(ReceiveMsg); // th.IsBackground = true;//主程序结束就退出,th.isbackground=false,线程结束才退出 //th.Start(); //} //catch (Exception ex) //{ // ShowMsg(ex.Message); //} client.BeginConnect(point, new AsyncCallback(ConnectCallback), client); Control.CheckForIllegalCrossThreadCalls = false; //消除跨线程 //连接成功后,就可以接收服务器发送的信息了 Thread th = new Thread(ReceiveMsg); th.IsBackground = true;//主程序结束就退出,th.isbackground=false,线程结束才退出 th.Start(); } private static void ConnectCallback(IAsyncResult ar) { try { // Retrieve the socket from the state object. Socket client = (Socket)ar.AsyncState; // Complete the connection. client.EndConnect(ar); Console.WriteLine("Socket connected to {0}", client.RemoteEndPoint.ToString()); // Signal that the connection has been made. connectDone.Set(); } catch (Exception e) { Console.WriteLine(e.ToString()); } } private void ShowMsg(string msg) { //TextBox textMsg = new TextBox(); textMsg.AppendText(msg+" "); } //接收服务器的消息 void ReceiveMsg() { //try //{ // byte[] buffer = new byte[1024 * 1024]; // int n = client.Receive(buffer); // string s = Encoding.UTF8.GetString(buffer, 0, n); // ShowMsg(client.RemoteEndPoint.ToString() + ":" + s); //} //catch (Exception ex) //{ // ShowMsg(ex.Message); // break; //} //client.Accept Receive(client); } private void btn_Send_Click_Click(object sender, EventArgs e) { //客户端给服务器发消息 //if (client != null) //{ // try // { // ShowMsg(textMsg.Text); // byte[] buffer = Encoding.UTF8.GetBytes(textMsg.Text); // client.Send(buffer); // } // catch (Exception ex) // { // ShowMsg(ex.Message); // } //} //byte[] buffer = Encoding.UTF8.GetBytes(textMsg.Text); Send(client, textLog.Text.ToString()); } private void Receive(Socket client) { try { // Create the state object. StateObject state = new StateObject(); //Socket ts = client.Accept(); state.workSocket = client; // Begin receiving the data from the remote device. client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReceiveCallback), state); } catch (Exception e) { Console.WriteLine(e.ToString()); } } private void ReceiveCallback(IAsyncResult ar) { try { // Retrieve the state object and the client socket // from the asynchronous state object. StateObject state = (StateObject)ar.AsyncState; Socket client = state.workSocket; // Read data from the remote device. int bytesRead = client.EndReceive(ar); if (bytesRead > 0) { // There might be more data, so store the data received so far. //state.sb.Append(Encoding.ASCII.GetString(state.buffer, 0, bytesRead)); string aa= Encoding.ASCII.GetString(state.buffer, 0, bytesRead); // Get the rest of the data. client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReceiveCallback), state); ShowMsg(client.RemoteEndPoint.ToString() + ":" + aa); } else { // All the data has arrived; put it in response. if (state.sb.Length > 1) { response = state.sb.ToString(); } // Signal that all bytes have been received. receiveDone.Set(); } } catch (Exception e) { Console.WriteLine(e.ToString()); } } private static void Send(Socket client, String data) { // Convert the string data to byte data using ASCII encoding. byte[] byteData = Encoding.ASCII.GetBytes(data); // Begin sending the data to the remote device. client.BeginSend(byteData, 0, byteData.Length, 0, new AsyncCallback(SendCallback), client); } private static void SendCallback(IAsyncResult ar) { try { // Retrieve the socket from the state object. Socket client = (Socket)ar.AsyncState; // Complete sending the data to the remote device. int bytesSent = client.EndSend(ar); Console.WriteLine("Sent {0} bytes to server.", bytesSent); // Signal that all bytes have been sent. sendDone.Set(); } catch (Exception e) { Console.WriteLine(e.ToString()); } } private void Client_Load(object sender, EventArgs e) { } private void textMsg_TextChanged(object sender, EventArgs e) { } } }
服务端
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Net; using System.Net.Sockets; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; namespace socketServer { public partial class socketServer : Form { public socketServer() { InitializeComponent(); } private void btn_Listen_Click(object sender, EventArgs e) { //ip地址 IPAddress ip = IPAddress.Parse(textIP.Text); //端口号 IPEndPoint point = new IPEndPoint(ip, int.Parse(textPort.Text)); //使用IPv4地址,流式socket方式,tcp协议传递数据 Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); try { //socket监听哪个端口 socket.Bind(point); //同一个时间点过来10个客户端,排队 socket.Listen(10); ShowMsg("服务器开始监听"); Control.CheckForIllegalCrossThreadCalls = false; Thread thread = new Thread(AcceptInfo); thread.IsBackground = true; thread.Start(socket); } catch (Exception ex) { throw; } } void ShowMsg(string msg) { textLog.AppendText(msg + " "); } //记录通信用的Socket Dictionary<string, Socket> dic = new Dictionary<string, Socket>(); void AcceptInfo(object o) { Socket socket = o as Socket; while (true) { //通信用socket try { //创建通信用的Socket Socket tSocket = socket.Accept(); string point = tSocket.RemoteEndPoint.ToString(); ShowMsg(point + "连接成功!"); comboBox1.Items.Add(point); dic.Add(point, tSocket); //接收消息 Thread th = new Thread(ReceiveMsg); th.IsBackground = true; th.Start(tSocket); } catch (Exception ex) { ShowMsg(ex.Message); break; } } } //接收消息 void ReceiveMsg(object o) { Socket client = o as Socket; while (true) { //接收客户端发送过来的数据 try { //定义byte数组存放从客户端接收过来的数据 byte[] buffer = new byte[1024 * 1024]; //将接收过来的数据放到buffer中,并返回实际接受数据的长度 int n = client.Receive(buffer); //将字节转换成字符串 string words = Encoding.UTF8.GetString(buffer, 0, n); ShowMsg(client.RemoteEndPoint.ToString() + ":" + words); } catch (Exception ex) { ShowMsg(ex.Message); break; } } } private void comboBox1_SelectedIndexChanged(object sender, EventArgs e) { } //给客户端发送消息 private void btn_Send_Click(object sender, EventArgs e) { try { ShowMsg(textMsg.Text); string ip = comboBox1.Text; byte[] buffer = Encoding.UTF8.GetBytes(textMsg.Text); dic[ip].Send(buffer); } catch (Exception ex) { ShowMsg(ex.Message); } } } }
client.beginconnection(point, new AsyncCallback(ConnectCallback), client);
client.BeginSend(byteData, 0, byteData.Length, 0, new AsyncCallback(SendCallback), client);
client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReceiveCallback), state);