简单的C# Socket通信实例
程序员文章站
2022-04-28 13:01:34
一、套接字(socket)概念 套接字(socket)是通信的基石,是支持TCP/IP协议的网络通信的基本操作单元。它是网络通信过程中端点的抽象表示,包含进行网络通信必须的五种信息:连接使用的协议,本地主机的IP地址,本地进程的协议端口,远地主机的IP地址,远地进程的协议端口。 应用层通过传输层进行 ......
一、套接字(socket)概念
套接字(socket)是通信的基石,是支持tcp/ip协议的网络通信的基本操作单元。它是网络通信过程中端点的抽象表示,包含进行网络通信必须的五种信息:连接使用的协议,本地主机的ip地址,本地进程的协议端口,远地主机的ip地址,远地进程的协议端口。
应用层通过传输层进行数据通信时,tcp会遇到同时为多个应用程序进程提供并发服务的问题。多个tcp连接或多个应用程序进程可能需要通过同一个 tcp协议端口传输数据。为了区别不同的应用程序进程和连接,许多计算机操作系统为应用程序与tcp/ip协议交互提供了套接字(socket)接口。应 用层可以和传输层通过socket接口,区分来自不同应用程序进程或网络连接的通信,实现数据传输的并发服务。
二、建立socket连接
建立socket连接至少需要一对套接字,其中一个运行于客户端,称为clientsocket ,另一个运行于服务器端,称为serversocket 。
套接字之间的连接过程分为三个步骤:服务器监听,客户端请求,连接确认。
- 服务器监听:服务器端套接字并不定位具体的客户端套接字,而是处于等待连接的状态,实时监控网络状态,等待客户端的连接请求
- 客户端请求:指客户端的套接字提出连接请求,要连接的目标是服务器端的套接字。为此,客户端的套接字必须首先描述它要连接的服务器的套接字,指出服务器端套接字的地址和端口号,然后就向服务器端套接字提出连接请求。
- 连接确认:当服务器端套接字监听到或者说接收到客户端套接字的连接请求时,就响应客户端套接字的请求,建立一个新的线程,把服务器端套接字的描述发给客户 端,一旦客户端确认了此描述,双方就正式建立连接。而服务器端套接字继续处于监听状态,继续接收其他客户端套接字的连接请求。
三、服务端与客户端代码
服务端前台xmal
1 <window x:class="socket通信.mainwindow" 2 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 3 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 4 xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 5 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 6 xmlns:local="clr-namespace:socket通信" 7 mc:ignorable="d" 8 title="服务端" height="350" width="525" loaded="window_loaded" > 9 <grid> 10 <grid.rowdefinitions> 11 <rowdefinition height="50*"/> 12 <rowdefinition height="190*"/> 13 <rowdefinition height="81*"/> 14 </grid.rowdefinitions> 15 <grid grid.row="0"> 16 <wrappanel verticalalignment="center"> 17 <label padding="5">ip:</label> 18 <textbox padding="3" width="150" name="ip"></textbox> 19 <label padding="5">port:</label> 20 <textbox padding="3" width="100" name="port"></textbox> 21 <button padding="3" margin="3" click="start_view_click">开始监听</button> 22 <button padding="3" margin="3" click="stop_click">停止监听</button> 23 </wrappanel> 24 </grid> 25 <grid grid.row="1"> 26 <listbox name="listconnet"></listbox> 27 </grid> 28 <grid grid.row="2"> 29 <grid.columndefinitions> 30 <columndefinition width="405*"/> 31 <columndefinition width="113*"/> 32 </grid.columndefinitions> 33 34 <textbox name="sentconnet"></textbox> 35 <button grid.column="1" click="send_click">发送</button> 36 37 </grid> 38 </grid> 39 </window>
服务端后台代码
1 using system; 2 using system.net; 3 using system.net.sockets; 4 using system.text; 5 using system.threading; 6 using system.windows; 7 8 9 10 namespace socket通信 11 { 12 /// <summary> 13 /// mainwindow.xaml 的交互逻辑 14 /// </summary> 15 public partial class mainwindow : window 16 { 17 public mainwindow() 18 { 19 initializecomponent(); 20 } 21 socket socketsend; 22 private void start_view_click(object sender, routedeventargs e) 23 { 24 try 25 { 26 //点击开始监听时 在服务端创建一个负责监听ip和端口号的socket 27 socket socketwatch = new socket(addressfamily.internetwork, sockettype.stream, protocoltype.tcp); 28 ipaddress ip = ipaddress.any; //创建对象端口 29 ipendpoint point = new ipendpoint(ip, convert.toint32(port.text)); 30 socketwatch.bind(point);//绑定端口号 31 showmsg("监听成功!"); 32 socketwatch.listen(10);//设置监听 33 //创建监听线程 34 thread thread = new thread(listen); 35 thread.isbackground = true; 36 thread.start(socketwatch); 37 } 38 catch { } 39 40 41 42 } 43 44 void listen(object o) 45 { 46 try 47 { 48 socket socketwatch = o as socket; 49 while (true) 50 { 51 socketsend = socketwatch.accept();//等待接收客户端连接 52 showmsg(socketsend.remoteendpoint.tostring() + ":" + "连接成功!"); 53 //开启一个新线程,执行接收消息方法 54 thread r_thread = new thread(received); 55 r_thread.isbackground = true; 56 r_thread.start(socketsend); 57 } 58 } 59 catch { } 60 } 61 62 63 64 /// <summary> 65 /// 服务器端不停的接收客户端发来的消息 66 /// </summary> 67 /// <param name="o"></param> 68 void received(object o) 69 { 70 try 71 { 72 socket socketsend = o as socket; 73 while (true) 74 { 75 //客户端连接服务器成功后,服务器接收客户端发送的消息 76 byte[] buffer = new byte[1024 * 1024 * 3]; 77 //实际接收到的有效字节数 78 int len = socketsend.receive(buffer); 79 if (len == 0) 80 { 81 break; 82 } 83 string str = encoding.utf8.getstring(buffer, 0, len); 84 showmsg("接收到的客户端数据:" + socketsend.remoteendpoint + ":" + str); 85 } 86 } 87 catch { } 88 } 89 /// <summary> 90 /// 服务器向客户端发送消息 91 /// </summary> 92 /// <param name="str"></param> 93 void send(string str) 94 { 95 byte[] buffer = encoding.utf8.getbytes(str); 96 socketsend.send(buffer); 97 } 98 99 void showmsg(string msg) 100 { 101 dispatcher.invoke(() => { listconnet.items.add(msg + "\r\n"); }); 102 } 103 104 105 106 private void send_click(object sender, routedeventargs e) 107 { 108 send(sentconnet.text.trim()); 109 } 110 111 private void window_loaded(object sender, routedeventargs e) 112 { 113 } 114 private void stop_click(object sender, routedeventargs e) 115 { 116 socketsend.close(); 117 showmsg("已经停止监听!"); 118 } 119 } 120 }
客户端前台xmal
1 <window x:class="socket_client.mainwindow" 2 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 3 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 4 xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 5 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 6 xmlns:local="clr-namespace:socket_client" 7 mc:ignorable="d" 8 title="客户端" height="350" width="525"> 9 <grid> 10 <grid.rowdefinitions> 11 <rowdefinition height="50*"/> 12 <rowdefinition height="190*"/> 13 <rowdefinition height="81*"/> 14 </grid.rowdefinitions> 15 <grid grid.row="0"> 16 <wrappanel verticalalignment="center"> 17 <label padding="5">ip:</label> 18 <textbox padding="3" width="150" name="ip"></textbox> 19 <label padding="5">port:</label> 20 <textbox padding="3" width="100" name="port"></textbox> 21 <button padding="3" margin="3" click="start_view_click">连接</button> 22 <button padding="3" margin="3" click="stop_click">断开连接</button> 23 </wrappanel> 24 </grid> 25 <grid grid.row="1"> 26 <textbox name="listconnet"></textbox> 27 </grid> 28 <grid grid.row="2"> 29 <grid.columndefinitions> 30 <columndefinition width="405*"/> 31 <columndefinition width="113*"/> 32 </grid.columndefinitions> 33 34 35 36 <textbox name="sentconnet"></textbox> 37 <button grid.column="1" click="send_click">发送</button> 38 39 </grid> 40 </grid> 41 </window>
客户端后台代码
1 using system; 2 using system.collections.generic; 3 using system.linq; 4 using system.net; 5 using system.net.sockets; 6 using system.text; 7 using system.threading; 8 using system.threading.tasks; 9 using system.windows; 10 using system.windows.controls; 11 using system.windows.data; 12 using system.windows.documents; 13 using system.windows.input; 14 using system.windows.media; 15 using system.windows.media.imaging; 16 using system.windows.navigation; 17 using system.windows.shapes; 18 19 20 21 namespace socket_client 22 { 23 /// <summary> 24 /// mainwindow.xaml 的交互逻辑 25 /// </summary> 26 public partial class mainwindow : window 27 { 28 public mainwindow() 29 { 30 initializecomponent(); 31 } 32 socket socketsend; 33 34 35 36 private void start_view_click(object sender, routedeventargs e) 37 { 38 try 39 { 40 //创建客户端socket,获得远程ip和端口号 41 socketsend = new socket(addressfamily.internetwork, sockettype.stream, protocoltype.tcp); 42 ipaddress ip = ipaddress.parse(ip.text); 43 ipendpoint point = new ipendpoint(ip, convert.toint32(port.text)); 44 45 socketsend.connect(point); 46 showmsg("连接成功!"); 47 //开启新的线程,不停的接收服务器发来的消息 48 thread c_thread = new thread(received); 49 c_thread.isbackground = true; 50 c_thread.start(); 51 } 52 catch (exception) 53 { 54 showmsg("ip或者端口号错误..."); 55 } 56 57 58 59 60 } 61 void showmsg(string str) 62 { 63 64 65 66 dispatcher.invoke(() => { listconnet.appendtext(str + "\r\n"); }); 67 } 68 /// <summary> 69 /// 接收服务端返回的消息 70 /// </summary> 71 void received() 72 { 73 while (true) 74 { 75 try 76 { 77 byte[] buffer = new byte[1024 * 1024 * 3]; 78 //实际接收到的有效字节数 79 int len = socketsend.receive(buffer); 80 if (len == 0) 81 { 82 continue; 83 } 84 string str = encoding.utf8.getstring(buffer, 0, len); 85 showmsg("接收到的服务端数据:" + socketsend.remoteendpoint + ":" + str); 86 } 87 catch 88 { 89 90 91 92 } 93 } 94 } 95 96 97 98 private void send_click(object sender, routedeventargs e) 99 { 100 try 101 { 102 string msg = sentconnet.text.trim(); 103 byte[] buffer = new byte[1024 * 1024 * 3]; 104 buffer = encoding.utf8.getbytes(msg); 105 socketsend.send(buffer); 106 } 107 catch { } 108 109 110 111 } 112 113 private void stop_click(object sender, routedeventargs e) 114 { 115 socketsend.close(); 116 showmsg("连接已经断开!"); 117 } 118 } 119 }
运行结果
上一篇: 你的一句话治好了她的眼睛
下一篇: 初识SpringCloud微服务