原文:C# Socket网络编程精华篇

转自:微冷的雨

我们在讲解Socket编程前,先看几个和Socket编程紧密相关的概念:

  1. 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主要有两种类型:

  1. 流式Socket

是一种面向连接的Socket,针对于面向连接的TCP服务应用,安全,但是效率低

2,数据报式Socket

是一种无连接的Socket,对应于无连接的UDP服务应用,不安全,但效率高

6. Socket一般应用模式(服务器端和客户端)

服务器端的Socket(至少需要两个)

01.一个负责接收客户端连接请求(但不负责与客户端通信)

02.每成功接收到客户端的连接便在服务器端产生一个对应的复杂通信的Socket

021.在接收到客户端连接时创建

022. 为每个连接成功的客户端请求在服务器端都创建一个对应的Socket(负责和客户端通信)

客户端的Socket

  1. 必须指定要连接的服务器地址和端口
  2. 通过创建一个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/CodeWorkerLiMing/p/11580326.html

Socket网络编程(TCP/IP/端口/类)和实例相关推荐

  1. C#中开发之Socket网络编程TCP/IP层次模型、端口及报文等探讨

    我们在讲解Socket编程前,先看几个和Socket编程紧密相关的概念 1.TCP/IP层次模型 当然这里我们只讨论重要的四层 01,应用层(Application):应用层是个很广泛的概念,有一些基 ...

  2. java socket ip_JAVA 网络编程 TCP/IP、Socket 和协议设计

    [JAVA 网络编程 TCP/IP.Socket 和协议设计] TCP/IP 协议简介 IP 首先我们看 IP(Internet Protocol)协议.IP 协议提供了主机和主机间的通信. 为了完成 ...

  3. WinSock API网络编程——TCP/IP协议详解

     WinSock API网络编程--TCP/IP协议(http://www.impcas.ac.cn/usr/lujun/browse.asp?id=winsock_tcp)            ...

  4. QT入门第七天 网络编程TCP/IP/UDP+Http和JSON解析+qt事件软键盘【CSDN最详细】

    网络编程+Http和JSON解析+qt事件软键盘 第一章 QT中的网络编程 [1]涉及到的类 [2]tcp协议的流程 [2.1]服务器的流程 socket-->bind-->listen- ...

  5. 网络编程-TCP/IP协议栈-TCP协议

    TCP协议 TCP协议作用 TCP协议位于协议栈的传输层.当应用层向TCP层发送用于网间传输的,用8字节表示的数据流,TCP则吧数据流分割成适当长度的报文段,最大传输段大小(MSS)通常受到改计算机连 ...

  6. 网络编程-TCP/IP协议栈-IP协议

    协议 协议就是约定的一种规则,例如扑克游戏中约定好的各种规则,2<3<4<5<-等,以此作为游戏规则.当所有人都遵循这个规则,那么久可以不需要任何多余的交流就可以进行游戏,这个 ...

  7. socket网络编程——TCP编程流程及端口号占用问题

    1.TCP编程流程 1.1TCP服务器端客户端及方法介绍 TCP 提供的是面向连接的.可靠的.字节流服务.TCP 的服务器端和客户端编程流程如下: socket()方法是用来创建一个套接字,有了套接字 ...

  8. python web开发 网络编程 TCP/IP UDP协议

    文章目录 1. TCP/IP协议 1.1 IP协议 1.2 TCP协议 2. UDP协议 3. Socket 4. TCP编程 4.1 创建TCP服务器 4.2 创建TCP客户端 4.3 简易聊天工具 ...

  9. 网络编程--TCP/IP协议(一)

    目录 前言 一丶网络基础 <1>认识IP地址 1>具体格式 2>组成 3>分类 4>子网掩码 <2>认识MAC地址 二丶网络设备及相关技术 <1& ...

最新文章

  1. table control中用帮助(F4)实现自动填充另一字段
  2. DescriptionAttribute Class
  3. 让Windows控制台应用程序支持VT100---原理篇
  4. google i/o_Google I / O 2017最有希望的突破
  5. java请编写公共类继承抽象类_(Java相关)怎么理解抽象类,继承和接口?
  6. 15款精美的 WordPress 电子商务网站模板
  7. 取得GridPanel选定行所有字段值
  8. OpenCV滤波器 龙门石窟篇【Python-Open_CV系列(九)】(均值滤波器、中值滤波器、高斯滤波器、双边滤波器)
  9. 从高考落榜生到网络专家
  10. 小米路由器mini刷linux,xiaomi mini路由器安装breed和openwrt固件
  11. Android debug时一直处于waiting for debugger解决办法
  12. nodejs压缩成7z_[Node] 传智NodeJS前端与移动开发顶级全套视频教程完整版
  13. vue关于时间顺序排序
  14. 第六天 色彩调整 2019-05-17
  15. Docker的文件系统
  16. 解决win10环境下安装ArcGIS提示需要Microsoft.NET Framework 3.5sp1或等效环境问题
  17. 对哈夫曼编码的输出 c语言,哈夫曼编码问题
  18. 2022年全国一级计算机基础及MS office应用历年真题及答案讲解
  19. 计算机第一代及第四代发展概况,计算机第一代至第四代的发展过程是什么?
  20. AP微积分应该怎么学?

热门文章

  1. Python分析《我们与恶的距离》豆瓣剧评
  2. Python使用multiprocessing实现多进程
  3. Django的模型类Meta
  4. 最新Win7 +Python3.6.0(Anaconda3-4.3.21)+Tensorflow的安装与配置(不用切换python3.5) 原创 2017年09月23日 15:14:58 标签:pyt
  5. jQuery事件之传递参数
  6. 深度学习- 激活函数总结(Sigmoid, Tanh, Relu, leaky Relu, PReLU, Maxout, ELU, Softmax,交叉熵函数)
  7. 系数矩阵为方阵的线性方程组解的情况
  8. 【什么是数据隐私?安全与隐私的区别?】差分隐私代码实现系列(一)
  9. 多元分类SVM(多类别SVM)程序使用说明
  10. IPC--进程间通信一(管道)