C# Socket网络编程精华篇
我们在讲解Socket编程前,先看几个和Socket编程紧密相关的概念:
- TCP/IP层次模型
当然这里我们只讨论重要的四层
01,应用层(Application):应用层是个很广泛的概念,有一些基本相同的系统级TCP/IP应用以及应用协议,也有许多的企业应用和互联网应用。http协议在应用层运行。
02,传输层(Tanspot):传输层包括UDP和TCP,UDP几乎不对报文进行检查,而TCP
提供传输保证。
03,网络层(Netwok):网络层协议由一系列协议组成,包括ICMP、IGMP、RIP、OSPF、IP(v4,v6)等。
04,链路层(Link):又称为物理数据网络接口层,负责报文传输。
然后我们来看下tcp层次模型图
从上图中可以看出,应用程序在应用层运行,在传输层,在数据前加上了TCP头,在
网络层加上的IP头,在数据链路层加上了帧。
2,端口
端口号范围:0-65535,总共能表示65536个数。
按端口号可分为3大类
(1)公认端口(WellKnownPorts):从0到1023,它们紧密绑定(binding)于一些服务。通常这些端口的通讯明确表明了某种服务的协议。例如:80端口实际上总是HTTP通讯。
(2)注册端口(RegisteredPorts):从1024到49151。它们松散地绑定于一些服务。也就是说有许多服务绑定于这些端口,这些端口同样用于许多其它目的。例如:许多系统处理动态端口从1024左右开始。
(3)动态和/或私有端口(Dynamicand/orPrivatePorts):从49152到65535。理论上,不应为服务分配这些端口。实际上,机器通常从1024起分配动态端口。
3.TCP和UDP报文
下面一起来看下TCP和UDP的报文图
从图中我们可以看出TCP和UDP中都有校验和,但是在UDP报文中,一般不使用校验和,这样可以加快数据传输的速度,但是数据的准确性可能会受到影响。换句话说,Tcp协议都有校验和,为了保证传输数据的准确性。
3.Socket
Socket包括Ip地址和端口号两部分,程序通过Socket来通信,Socket相当于操作系统的一个组件。Socket作为进程之间通信机制,通常也称作”套接字”,用于描述IP地址和端口号,是一个通信链的句柄。说白了,就是两个程序通信用的。
生活案例对比:
Socket之间的通信可以类比生活中打电话的案例。任何用户在通话之前,首先要占有一部电话机,相当于申请一个Socket,同时要知道对方的号码,相当于对方有一个固定的Socket,然后向对方拨号呼叫,相当于发出连接请求。假如对方在场并空闲,拿起 电话话筒,双方就可以进行通话了。双方的通话过程,是一方向电话机发出信号和对方从电话机接收信号的过程,相当于向socket发送数据和从socket接收数据。通话结束后,一方挂起电话机,相当于关闭socket,撤销连接。
注意:Socket不仅可以在两台电脑之间通信,还可以在同一台电脑上的两个程序间通信。
4,端口进阶(深入)
通过IP地址确定了网络中的一台电脑后,该电脑上可能提供很多提供服务的应用,每一个应用都对应一个端口。
在Internet上有很多这样的主机,这些主机一般运行了多个服务软件 ,同时提供几种服务,每种服务都打开一个Socket,并绑定到一个端口上,不同的端口对应于不同的服务(应用程序)
例如:http 使用80端口, ftp使用21端口 smtp使用25端口
5.Socket分类
Socket主要有两种类型:
- 流式Socket
是一种面向连接的Socket,针对于面向连接的TCP服务应用,安全,但是效率低
2,数据报式Socket
是一种无连接的Socket,对应于无连接的UDP服务应用,不安全,但效率高
6. Socket一般应用模式(服务器端和客户端)
服务器端的Socket(至少需要两个)
01.一个负责接收客户端连接请求(但不负责与客户端通信)
02.每成功接收到客户端的连接便在服务器端产生一个对应的复杂通信的Socket
021.在接收到客户端连接时创建
022. 为每个连接成功的客户端请求在服务器端都创建一个对应的Socket(负责和客户端通信)
客户端的Socket
- 必须指定要连接的服务器地址和端口
- 通过创建一个Socket对象来初始化一个到服务器端的TCP连接
通过上图,我们可以看出,首先服务器会创建一个负责监听的socket,然后客户端通过socket连接到服务器指定端口,最后服务器端负责监听的socket,监听到客户端有连接过来了,就创建一个负责和客户端通信的socket。
下面我们来看下Socket更具体的通信过程:
Socket的通讯过程
服务器端:
01,申请一个socket
02,绑定到一个IP地址和一个端口上
03,开启侦听,等待接收连接
客户端:
01,申请一个socket
02,连接服务器(指明IP地址和端口号)
服务器端接收到连接请求后,产生一个新的socket(端口大于1024)与客户端建立连接并进行通信,原监听socket继续监听。
注意:负责通信的Socket不能无限创建,创建的数量和操作系统有关。
7.Socket的构造函数
Public Socket(AddressFamily addressFamily,SocketType socketType,ProtocolType protocolTYpe)
AddressFamily:指定Socket用来解析地址的寻址方案。例如:InterNetWork指示当Socket使用一个IP版本4地址连接
SocketType:定义要打开的Socket的类型
Socket类使用ProtocolType枚举向Windows Sockets API通知所请求的协议
注意:
1,端口号必须在 1 和 65535之间,最好在1024以后。
2,要连接的远程主机必须正在监听指定端口,也就是说你无法随意连接远程主机。
如:
IPAddress addr = IPAddress.Parse("127.0.0.1");
IPEndPoint endp = new IPEndPoint(addr,,9000);
服务端先绑定:serverWelcomeSocket.Bind(endp)
客户端再连接:clientSocket.Connect(endp)
3,一个Socket一次只能连接一台主机
4,Socket关闭后无法再次使用
5,每个Socket对象只能与一台远程主机连接。如果你想连接到多台远程主机,你必须创建多个Socket对象。
8.Socket常用类和方法
相关类:
IPAddress:包含了一个IP地址
IPEndPoint:包含了一对IP地址和端口号
方法:
Socket():创建一个Socket
Bind():绑定一个本地的IP和端口号(IPEndPoint)
Listen():让Socket侦听传入的连接吃那个病,并指定侦听队列容量
Connect():初始化与另一个Socket的连接
Accept():接收连接并返回一个新的Socket
Send():输出数据到Socket
Receive():从Socket中读取数据
Close():关闭Socket,销毁连接
接下来,我们同一个简单的服务器和客户端通信的案例,来看下Sokcet的具体用法,效果图如下:
关键代码:
服务器端代码:
1 private void Form1_Load(object sender, EventArgs e)2 3 {4 5 Control.CheckForIllegalCrossThreadCalls = false;6 7 }8 9 10 11 private void btnListen_Click(object sender, EventArgs e)12 13 {14 15 //ip地址16 17 IPAddress ip = IPAddress.Parse(txtIP.Text);18 19 // IPAddress ip = IPAddress.Any;20 21 //端口号22 23 IPEndPoint point=new IPEndPoint(ip,int.Parse(txtPort.Text));24 25 //创建监听用的Socket26 27 /*28 29 * AddressFamily.InterNetWork:使用 IP4地址。30 31 SocketType.Stream:支持可靠、双向、基于连接的字节流,而不重复数据。此类型的 Socket 与单个对方主机进行通信,并且在通信开始之前需要远程主机连接。Stream 使用传输控制协议 (Tcp) ProtocolType 和 InterNetworkAddressFamily。32 33 ProtocolType.Tcp:使用传输控制协议。34 35 */36 37 //使用IPv4地址,流式socket方式,tcp协议传递数据38 39 Socket socket=new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);40 41 //创建好socket后,必须告诉socket绑定的IP地址和端口号。42 43 //让socket监听point44 45 try46 47 {48 49 //socket监听哪个端口50 51 socket.Bind(point);52 53 //同一个时间点过来10个客户端,排队54 55 socket.Listen(10);56 57 ShowMsg("服务器开始监听");58 59 Thread thread = new Thread(AcceptInfo);60 61 thread.IsBackground = true;62 63 thread.Start(socket);64 65 }66 67 catch (Exception ex)68 69 {70 71 72 73 ShowMsg(ex.Message);74 75 }76 77 }78 79 //记录通信用的Socket80 81 Dictionary<string,Socket> dic=new Dictionary<string, Socket>();82 83 // private Socket client;84 85 void AcceptInfo(object o)86 87 {88 89 Socket socket = o as Socket;90 91 while (true)92 93 {94 95 //通信用socket96 97 try98 99 { 100 101 //创建通信用的Socket 102 103 Socket tSocket = socket.Accept(); 104 105 string point = tSocket.RemoteEndPoint.ToString(); 106 107 //IPEndPoint endPoint = (IPEndPoint)client.RemoteEndPoint; 108 109 //string me = Dns.GetHostName();//得到本机名称 110 111 //MessageBox.Show(me); 112 113 ShowMsg(point + "连接成功!"); 114 115 cboIpPort.Items.Add(point); 116 117 dic.Add(point, tSocket); 118 119 //接收消息 120 121 Thread th = new Thread(ReceiveMsg); 122 123 th.IsBackground = true; 124 125 th.Start(tSocket); 126 127 } 128 129 catch (Exception ex) 130 131 { 132 133 ShowMsg(ex.Message); 134 135 break; 136 137 } 138 139 } 140 141 } 142 143 //接收消息 144 145 void ReceiveMsg(object o) 146 147 { 148 149 Socket client = o as Socket; 150 151 while (true) 152 153 { 154 155 //接收客户端发送过来的数据 156 157 try 158 159 { 160 161 //定义byte数组存放从客户端接收过来的数据 162 163 byte[] buffer = new byte[1024 * 1024]; 164 165 //将接收过来的数据放到buffer中,并返回实际接受数据的长度 166 167 int n = client.Receive(buffer); 168 169 //将字节转换成字符串 170 171 string words = Encoding.UTF8.GetString(buffer, 0, n); 172 173 174 175 ShowMsg(client.RemoteEndPoint.ToString() + ":" + words); 176 177 } 178 179 catch (Exception ex) 180 181 { 182 183 ShowMsg(ex.Message); 184 185 break; 186 187 } 188 189 } 190 191 } 192 193 194 195 void ShowMsg(string msg) 196 197 { 198 199 txtLog.AppendText(msg+"\r\n"); 200 201 } 202 203 204 205 private void Form1_FormClosing(object sender, FormClosingEventArgs e) 206 207 { 208 209 //主窗体关闭时关闭子线程 210 211 212 213 } 214 215 //给客户端发送消息 216 217 private void btnSend_Click(object sender, EventArgs e) 218 219 { 220 221 try 222 223 { 224 225 ShowMsg(txtMsg.Text); 226 227 string ip = cboIpPort.Text; 228 229 byte[] buffer = Encoding.UTF8.GetBytes(txtMsg.Text); 230 231 dic[ip].Send(buffer); 232 233 // client.Send(buffer); 234 235 } 236 237 catch (Exception ex) 238 239 { 240 241 ShowMsg(ex.Message); 242 243 } 244 245 246 247 }
客户端代码:
1 Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);2 3 private void btnConnection_Click(object sender, EventArgs e)4 5 {6 7 //连接到的目标IP8 9 IPAddress ip = IPAddress.Parse(txtIP.Text);10 11 //IPAddress ip = IPAddress.Any;12 13 //连接到目标IP的哪个应用(端口号!)14 15 IPEndPoint point=new IPEndPoint(ip,int.Parse(txtPort.Text));16 17 try18 19 {20 21 //连接到服务器22 23 client.Connect(point);24 25 ShowMsg("连接成功");26 27 ShowMsg("服务器" + client.RemoteEndPoint.ToString());28 29 ShowMsg("客户端:" + client.LocalEndPoint.ToString());30 31 //连接成功后,就可以接收服务器发送的信息了32 33 Thread th=new Thread(ReceiveMsg);34 35 th.IsBackground = true;36 37 th.Start();38 39 }40 41 catch (Exception ex)42 43 {44 45 ShowMsg(ex.Message);46 47 }48 49 }50 51 //接收服务器的消息52 53 void ReceiveMsg()54 55 {56 57 while (true)58 59 {60 61 try62 63 {64 65 byte[] buffer = new byte[1024 * 1024];66 67 int n = client.Receive(buffer);68 69 string s = Encoding.UTF8.GetString(buffer, 0, n);70 71 ShowMsg(client.RemoteEndPoint.ToString() + ":" + s);72 73 }74 75 catch (Exception ex)76 77 {78 79 ShowMsg(ex.Message);80 81 break;82 83 }84 85 }86 87 88 89 }90 91 92 93 void ShowMsg(string msg)94 95 {96 97 txtInfo.AppendText(msg+"\r\n");98 99 } 100 101 102 103 private void btnSend_Click(object sender, EventArgs e) 104 105 { 106 107 //客户端给服务器发消息 108 109 if (client!=null) 110 111 { 112 113 try 114 115 { 116 117 ShowMsg(txtMsg.Text); 118 119 byte[] buffer = Encoding.UTF8.GetBytes(txtMsg.Text); 120 121 client.Send(buffer); 122 123 } 124 125 catch (Exception ex) 126 127 { 128 129 ShowMsg(ex.Message); 130 131 } 132 133 } 134 135 136 137 } 138 139 140 141 private void ClientForm_Load(object sender, EventArgs e) 142 143 { 144 145 Control.CheckForIllegalCrossThreadCalls = false; 146 147 }
转载于:https://www.cnblogs.com/asdyzh/p/9839775.html
C# Socket网络编程精华篇相关推荐
- C# Socket网络编程精华篇 (转)
http://www.cnblogs.com/weilengdeyu/archive/2013/03/08/2949101.html 我们在讲解Socket编程前,先看几个和Socket编程紧密相关的 ...
- Socket网络编程(TCP/IP/端口/类)和实例
原文:C# Socket网络编程精华篇 转自:微冷的雨 我们在讲解Socket编程前,先看几个和Socket编程紧密相关的概念: TCP/IP层次模型 当然这里我们只讨论重要的四层 01,应用层(Ap ...
- Socket网络编程(2)--服务端实现
中秋了,首先祝大家中秋快乐,闲着无事在家整一个socket的聊天程序,有点仿QQ界面,就是瞎折腾,不知道最后是不是能将所有功能实现. 如果你对socket不了解,请看这篇文章:http://www.c ...
- Python Socket网络编程(二)局域网内和局域网与广域网的持续通信
目录 前言 IP地址 简介 公有IP 私有IP 局域网之间网络通信 前提 功能描述 源码 运行结果 局域网与广域网网络通信 前提 源码 结语 前言 本系列博客是笔者学习Python Socket的过程 ...
- Python Socket网络编程(一)初识Socket和Socket初步使用
目录 前言 网络编程 实质 IP地址和端口 数据传输协议 协议 Socket 概念 套接字 socket对象方法 初步使用 功能 源码 运行结果 结语 前言 本系列博客是笔者学习Python Sock ...
- 【Socket网络编程进阶与实战】------ Socket网络编程快速入门
前言 本篇博客主要是分享,socket网络编程进阶与实践☞socket网络编程快速入门 一.聊一聊Socket 学习目标与收获
- python开发之Socket网络编程
python开发之Socket网络编程 一.SOCKET基础 二.SOCKET通信流程 1. 流程描述: 2. 相关方法及参数介绍: 三.实例(屌丝追女神的故事) 1. 故事1:(一次通信) 2. 故 ...
- 《C#网络编程高级篇之网页游戏辅助程序设计(扫描版)》
<C#网络编程高级篇之网页游戏辅助程序设计>通过编写C#网络编程语言中具有代表性的实例,向读者深入细致地讲解了如何利用C#语言进行网页游戏辅助程序设计.本书通过大量的代码引导读者一步步学习 ...
- 【Linux】socket网络编程之服务器与客户端的数据交互
[Linux]socket网络编程之服务器与客户端的数据交互 前言参考 argc !=2是什么意思 inet pton函数 对stdin,stdout 和STDOUT_FILENO,STDIN_FIL ...
最新文章
- 如何短时间提高python面向对象_初识Python面向对象阶段,你们都是怎么过来的?
- int ,long , long long类型的范围
- OpenCV学习笔记(十一)(十二)(十三)(十四)(十五)
- 记录一下Memcached的用法:
- 若川的2016年度总结,毕业工作
- Android之如何解决android.os.NetworkOnMainThreadException的异常
- 化工图纸中LISP_化工设备厂参展模型设计制作
- ​我拿 12 年 36 套四级真题做了什么 ?
- LINUX下载ant源码并编译
- 年薪201W!华为新天才少年出炉:武大94年博士生入选!任正非最新发声:江山代有才人出,不拘一格降人才!...
- 计算机关闭测试模式,win10怎么开启及关闭测试模式 win10测试模式对电脑有影响吗...
- 经济危机离你并不遥远!
- 网络安全-使用PGP实现电子邮件安全
- 二分法查找--Dichotomy search
- 城市内涝一维二维耦合技术及在城市排水防涝领域中的实践应用
- 【spring 的 init and destory 方法】
- 多示例学习距离度量 (distance measures)和集合核 (set-kernel)
- os.path.dirname()用法
- 互联网上要创业 选好域名很重要
- [图解] 勒索病毒加密原理