Socket
一、网络七层协议 / OSI 七层模型
2.1 物理层
解决两个硬件之间怎么通信的问题,常见的物理媒介有光纤、电缆、中继器等。它主要定义物理设备标准,如网线的接口类型、光纤的接口类型、各种传输介质的传输速率等。
它的主要作用是传输比特流(就是由1、0转化为电流强弱来进行传输,到达目的地后在转化为1、0,也就是我们常说的数模转换与模数转换)。这一层的数据叫做比特。
2.2 数据链路层
在计算机网络中由于各种干扰的存在,物理链路是不可靠的。该层的主要功能就是:通过各种控制协议,将有差错的物理信道变为无差错的、能可靠传输数据帧的数据链路。
它的具体工作是接收来自物理层的位流形式的数据,并封装成帧,传送到上一层;同样,也将来自上层的数据帧,拆装为位流形式的数据转发到物理层。这一层的数据叫做帧。
传输的过程中,0和1到底有啥意义?
组建一个固定的格式;
Head:描述信息
Data:真正的数据源,还可以做拆分成多块;
你好 ---- 0101001;
局域网内:A 如何把信息传递给B?
MAC地址:就是每一台计算都有一个唯一的标识;
就可以基于MAC(网卡)地址;
广播:先广播,A带上自己的mac地址,广播信号出去,其他的电脑,回传自己的mac地址;A就就知道要传给谁;还是继续广播;带上接收方的mac地址;
2.3 网络层
计算机网络中如果有多台计算机,怎么找到要发的那台?如果中间有多个节点,怎么选择路径?这就是路由要做的事。
该层的主要任务就是:通过路由选择算法,为报文(该层的数据单位,由上一层数据打包而来)通过通信子网选择最适当的路径。这一层定义的是IP地址,通过IP地址寻址,所以产生了IP协议。
怎么确定?
这里可以定位到互联网上的某一个子网络;
通过IP地址来确定;
确定到子网络以后+MAC定位=具体的是那一台计算机; 形成互动;
2.4 传输层
当发送大量数据时,很可能会出现丢包的情况,另一台电脑要告诉是否完整接收到全部的包。如果缺了,就告诉丢了哪些包,然后再发一次,直至全部接收为止。
简单来说,传输层的主要功能就是:监控数据传输服务的质量,保证报文的正确传输。
数据已经可以明确的传输到某一台电脑上;
如何定位到某一个进程?
基于以上部分+端口号=具体的某一个程序;
范围:0-65535;
你们的程序尽量不要指定端口为;0-1023这类数据为端口;很可能会系统中;
基于不同的协议来:UDP协议:head里只是记录了端口号;Data部分分为head+data;
简单:传输快;可能会丢包;传输的时候没有确认应答;具体不知道接收是否真正的接收到了;
TCP:传输弱于UDP,不会丢包;有确认机制;
三次握手:—客户端发送服务器1—服务器向客户端发个2 服务器还要 再发送a,客户端返回一个b;、
建立连接;
开始通信;如果不主动取消,会长期连接;
2.5 会话层
虽然已经可以实现给正确的计算机,发送正确的封装过后的信息了。但我们总不可能每次都要调用传输层协议去打包,然后再调用IP协议去找路由,所以我们要建立一个自动收发包,自动寻址的功能。于是会话层出现了:它的作用就是建立和管理应用程序之间的通信。
2.6 表示层
表示层负责数据格式的转换,将应用处理的信息转换为适合网络传输的格式,或者将来自下一层的数据转换为上层能处理的格式。
2.7 应用层
应用层是计算机用户,以及各种应用程序和网络之间的接口,其功能是直接向用户提供服务,完成用户希望在网络上完成的各种工作。前端同学对应用层肯定是最熟悉的。
最后,给大家横向对比下TCP/IP4层模型、5层模型和OSI七层模型的差别:
二、UDP/TCP
UDP协议:head里只是记录了端口号;Data部分分为head+data;
简单:传输快;可能会丢包;传输的时候没有确认应答;具体不知道接收是否真正的接收到了;
TCP:传输弱于UDP,不会丢包;有确认机制;
三次握手:—客户端发送服务器1—服务器向客户端发个2 服务器还要 再发送a,客户端返回一个b;、
建立连接;
开始通信;如果不主动取消,会长期连接;
三、协议
在浏览器输入一个www.baidu.com;
- 需要DNS服务器解析域名;IP地址:端口的映射;
- DNS服务器把映射结果响应给浏览器;
- 浏览器把请求的数据打包:通过网卡发送信息;—根据子网掩码+IP计算—确定到某一个子网+Port;
- 服务器任何时候都是监控者这个端口号的;
- TCP三次握手了,建立连接,发包;
- 服务器拿到数据包—排序—获取到所有的字符串;按照Http协议解析这个数据包;
四、Socket 实战
4.1 简单Socket客户端
我们一般常使用的其实是Http请求; 属于一种单向通信,客户端===服务器 请求响应式
socket==套接字,长链接、双工通信,可以让客户单和服务器之间相互发送消息
int port = 2018;
string host = "127.0.0.1";//服务器端ip地址
IPAddress ip = IPAddress.Parse(host);
IPEndPoint ipe = new IPEndPoint(ip, port);
Socket clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
clientSocket.Connect(ipe); //开启链接以后,是长链接;
while (true)
{
Console.WriteLine("请输入发送到服务器的信息:");
string sendStr = Console.ReadLine();
if (sendStr == "exit")
break;
byte[] sendBytes = Encoding.ASCII.GetBytes(sendStr);
clientSocket.Send(sendBytes);
//receive message
string recStr = "";
byte[] recBytes = new byte[4096];
//监控传递过来的消息;
int bytes = clientSocket.Receive(recBytes, recBytes.Length, 0);
recStr += Encoding.ASCII.GetString(recBytes, 0, bytes);
Console.WriteLine($"服务器返回:{recStr}");
}
clientSocket.Close();
4.2 简单Socket服务端
**SimpleSocketServer.cs **
public static void Proccess()
{
int port = 2018;
string host = "127.0.0.1";
IPAddress ip = IPAddress.Parse(host);
IPEndPoint ipe = new IPEndPoint(ip, port);
Socket sSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
sSocket.Bind(ipe);
sSocket.Listen(0);
Console.WriteLine("监听已经打开,请等待");
//收到消息 接受一个socket链接
Socket serverSocket = sSocket.Accept();
Console.WriteLine("连接已经建立。。。");
while (true)
{
string recStr = "";
byte[] recByte = new byte[4096];
int bytes = serverSocket.Receive(recByte, recByte.Length, 0);
recStr += Encoding.ASCII.GetString(recByte, 0, bytes);
Console.WriteLine("服务器端获得信息:{0}", recStr);
if (recStr.Equals("stop"))
{
serverSocket.Close();//关闭该socket对象
Console.WriteLine("关闭链接。。。。");
break;
}
//回发消息
Console.WriteLine("请输入回发消息。。。。");
string sendStr = Console.ReadLine(); //"send to client :hello world";
byte[] sendByte = Encoding.ASCII.GetBytes(sendStr);
serverSocket.Send(sendByte, sendByte.Length, 0);
}
sSocket.Close();//关闭server监听
}