Day16_C#_Socket网络编程
01. Socket 一般应用模式 (C/S)
02. Socket 通讯基本流程
03. 服务端代码编写 (注意Socket的Accept是阻塞模式的,需要线程下处理;接收模式下,如果是阻塞模式,同样需要线程处理)
1 namespace Chat 2 { 3 public partial class Form1 : Form 4 { 5 public Form1() 6 { 7 InitializeComponent(); 8 } 9 10 //监听Socket 11 Socket socketWatch; 12 //客户端在线集合 13 Dictionary<string, Socket> clients = new Dictionary<string, Socket>(); 14 15 16 private void btn_service_Click(object sender, EventArgs e) 17 { 18 //点击开始监听后,在服务端创建一个socket,用于监听服务器上的某个端口,用于客户端连接请求业务的处理 19 socketWatch = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); 20 //IPAddress ip = IPAddress.Any; 21 IPAddress ip = IPAddress.Parse(txt_ip.Text); 22 IPEndPoint point = new IPEndPoint(ip, Convert.ToInt32(txt_port.Text)); 23 //监听端口绑定 24 socketWatch.Bind(point); 25 //开始监听 26 socketWatch.Listen(1000); 27 //开始接收(为避免占用主线程,开新线程监听) 28 Thread thread = new Thread(startAccept); 29 thread.IsBackground = true; 30 thread.Start(socketWatch); 31 } 32 33 void startAccept(object o) 34 { 35 Socket sc = o as Socket; 36 37 while (true) 38 { 39 //等待监听,创建通讯socket 40 Socket socketCon = sc.Accept(); 41 //将客户端记录起来 42 clients.Add(socketCon.RemoteEndPoint.ToString(), socketCon); 43 //在下拉列表中展示 44 cb_clients.Items.Add(socketCon.RemoteEndPoint.ToString()); 45 if (cb_clients.SelectedIndex < 0) 46 { 47 cb_clients.SelectedIndex = 0; 48 } 49 //连接展示 50 ShowMsg(socketCon.RemoteEndPoint.ToString() + ":连接成功."); 51 //激活通讯Socket, 52 Thread cThread = new Thread(recvMsg); 53 cThread.IsBackground = true; 54 cThread.Start(socketCon); 55 } 56 } 57 58 void recvMsg(Object o) 59 { 60 Socket con = o as Socket; 61 byte[] buf = new byte[1024 * 1024 * 5]; 62 while (true) 63 { 64 int r = con.Receive(buf); 65 if (r <= 0) 66 { 67 continue; 68 } 69 string recvMsg = Encoding.UTF8.GetString(buf, 0, r); 70 ShowMsg(con.RemoteEndPoint.ToString() + ":" + recvMsg); 71 } 72 } 73 74 /// <summary> 75 /// 日志记录 76 /// </summary> 77 /// <param name="str"></param> 78 void ShowMsg(string str) 79 { 80 txt_RecvMsg.AppendText(str + "\r\n"); 81 } 82 83 private void Form1_Load(object sender, EventArgs e) 84 { 85 Control.CheckForIllegalCrossThreadCalls = false; 86 } 87 88 private void btn_sendMsg_Click(object sender, EventArgs e) 89 { 90 if (cb_clients.SelectedIndex < 0) 91 { 92 ShowMsg("请选择目标对象后再发送消息"); 93 return; 94 } 95 //取发送消息 96 string sendMsg = txt_Send.Text.Trim(); 97 byte[] sendBuf = Encoding.UTF8.GetBytes(sendMsg); 98 //取当前目标对象 99 string ip = cb_clients.SelectedItem.ToString(); 100 //取目标客户端 101 Socket client = clients[ip]; 102 //发送消息 103 client.Send(sendBuf); 104 105 } 106 } 107 }
>> 关联界面
04. 客户端代码编写
1 namespace ChatClient 2 { 3 public partial class Form1 : Form 4 { 5 public Form1() 6 { 7 InitializeComponent(); 8 } 9 10 Socket sc; 11 12 private void btn_Connect_Click(object sender, EventArgs e) 13 { 14 sc = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); 15 16 IPAddress ip = IPAddress.Parse(txt_ip.Text); 17 IPEndPoint point = new IPEndPoint(ip, Convert.ToInt32(txt_port.Text)); 18 19 sc.Connect(point); 20 ShowMsg("连接成功"); 21 22 //新开线程,用于接收服务端返回的消息 23 Thread thread = new Thread(recvMsg); 24 thread.IsBackground = true; 25 thread.Start(sc); 26 } 27 28 void recvMsg(Object o) 29 { 30 Socket con = o as Socket; 31 byte[] buf = new byte[1024 * 1024 * 5]; 32 while (true) 33 { 34 int r = con.Receive(buf); 35 if (r <= 0) 36 { 37 continue; 38 } 39 string recvMsg = Encoding.UTF8.GetString(buf, 0, r); 40 ShowMsg(con.RemoteEndPoint.ToString() + ":" + recvMsg); 41 } 42 } 43 44 45 /// <summary> 46 /// 日志记录 47 /// </summary> 48 /// <param name="str"></param> 49 void ShowMsg(string str) 50 { 51 txt_RecvMsg.AppendText(str + "\r\n"); 52 } 53 54 private void Form1_Load(object sender, EventArgs e) 55 { 56 Control.CheckForIllegalCrossThreadCalls = false; 57 } 58 59 private void btn_sendMsg_Click(object sender, EventArgs e) 60 { 61 string str = txt_Send.Text.Trim(); 62 byte[] sednBytes = Encoding.UTF8.GetBytes(str); 63 sc.Send(sednBytes); 64 65 } 66 } 67 }
>> 关联界面