UN3L1——FTP工作原理
UN3L1——FTP工作原理
FTP
FTP(File Transfer Protocol)文件传输协议,是支持Internet文件传输的各种规则所组成的集合
这些规则使Internet用户可以把文件从一台主机拷贝到另一台主机上
除此之外,FTP还提供登录、目录查询以及其他会话控制等功能
说人话:FTP文件传输协议就是一个在网络中上传下载文件的一套规则
FTP的工作原理
划重点:FTP的本质是TCP通信
通过FTP传输文件,双发至少需要建立两个TCP连接
一个称为控制连接,用于传输FTP命令
一个称为数据连接,用于传输文件数据
FTP的数据连接和控制连接方向一般是相反的,举例说明:
用户使用FTP客户端连接FTP服务区请求下载文件
控制连接方向:客户端主动连接服务器告知其下载命令(C ——> S)
数据连接方向:服务端主动连接客户端下发数据(C <—— S)
当客户端和FTP服务器建立控制连接后,需要告诉服务器采用那种传输模式:
主动模式(Port模式) :服务器主动连接客户端,然后传输文件
被动模式(Passive模式) :客户端主动连接服务器,即控制连接和数 ...
UN3——FTP网络通信方案
UN3——FTP网络通信方案
FTP
文件传输协议(File Transfer Protocol,FTP)是用于在网络上进行文件传输的一套标准协议
FTP允许用户以文件操作的方式(如文件的增、删、改、查、传送等)与另一主机相互通信。
然而,用户并不真正登录到自己想要存取的计算机上面而成为完全用户,可用FTP程序访问远程资源,
实现用户往返传输文件、目录管理以及访问电子邮件等等,即使双方计算机可能配有不同的操作系统和文件存储方式。
FTP(文件传输协议)_百度百科 (baidu.com)
本系列学习内容
FTP工作原理
搭建FTP服务器
FTP关键类
上传文件
下载文件
其它操作
UN2L12——UDP异步通信常用方法
UN2L12——UDP异步通信常用方法
本章代码关键字
1234567socket.BeginSendTo() //异步发送消息,传入字节数组,偏移量,最大发送字节数,标识,目标IP与端口,回调函数和回调函数的参数socket.EndSendTo() //结束异步发送消息,传入回调函数的参数,返回发送了多少字节socket.BeginReceiveFrom() //异步接收消息,传入字节数组,偏移量,最大接收字节数,标识,记录发送者IP与端口的对象,回调函数和回调函数的参数socket.EndReceiveFrom() //结束异步接收消息方法,传入回调函数的参数,返回接收了多少字节socketAsyncEventArgs.RemoteEndPoint //设置发送到哪个IP地址和端口号或者记录发送者IP地址和端口号的属性socket.SendToAsync() //异步发送消息soc ...
UN2L11——服务端和客户端同步通信
UN2L11——服务端和客户端同步通信
本章代码关键字
12socket.SendTo()socket.ReceiveFrom()
UDP同步收发消息API
同步发送消息
UDP同步通信中,一般用SendTo来发送消息,使用前不需要建立连接,只需要绑定好本机IP即可
该方法有多种重载,最基础的重载参数包括:发送的字节数组、要发送的IP地址和端口号
参数一:发送的字节数组(必须)
参数二:偏移量,即从第几位开始发送
参数三:要发送多少字节
参数四:套接字标识
参数五:要发送的IP地址和端口号(必须)
12345678//创建套接字Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);//绑定本机地址IPEndPoint ipPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 8080);socket.Bind(ipPoint);//发送到指定目标,指定要发送的字节数组和远程计算 ...
UN2L10——UDP通信概述
UN2L10——UDP通信概述
服务端和客户端需要做什么
UDP通信逻辑要比TCP通信的逻辑更简单一点,UDP中客户端与服务器端要做的事情大同小异,细节上有差异
客户端和服务端
创建套接字Socket
用Bind方法将套接字与本地地址进行绑定
用ReceiveFrom和SendTo方法在套接字上收发消息
用Shutdown方法释放连接
关闭套接字
UDP相对TCP的区别
TCP通信与UDP通信逻辑上的区别:
分包、黏包问题
UDP不会黏包
因为UDP不可靠,我们要避免其自动分包,消息大小要控制在一定范围内
但是我们可以根据自己的需求自己在实现逻辑时加入分包黏包功能:
消息过小可以手动黏包
消息过大可以手动分包
但是对于手动分包,我们必须解决UDP无序和丢包的问题
黏包问题
UDP本身作为无连接的不可靠的传输协议(适合频繁发送较小的数据包),他不会对数据包进行合并发送
一端发送什么数据,直接就发出去了,他不会对数据合并,因此在UDP当中不会出现黏包问题(除非你手动进行黏包)
分包问题
由于UDP是不可靠的连接,消息传递过程中可能出现无序、丢包 ...
UN2L9——服务端和客户端异步通信
UN2L9——服务端和客户端异步通信
服务端Socket的TCP异步通信
暂时不考虑区分消息类型,分包、黏包以及心跳消息等功能,实现一个基础的服务端
ServerClient.cs
clientDic:用于管理各个连接客户端的Socket,可以通过ID来获取单个Socket
Start:提供给外部开启并初始化服务端Socket的方法,使用异步方法开启监听客户端连入
AcceptCallBack:监听客户端连入异步方法的回调方法,处理连接客户端的Socket,并开启下一次监听客户端连入
BroadCast:让所有的ClientSocket发送传入的广播消息
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556using System.Net;using System.Net.Sockets;namespace TeachTcpServerAsync{ internal class ServerSoc ...
UN2L8——TCP异步通信常用方法
UN2L8——TCP异步通信常用方法
本章代码关键字
12345678910111213141516171819202122232425//Begin开头的API:内部开多线程,通过回调形式返回结果,需要和End相关方法配合使用IAsyncResult //所有Begin开头的API都会返回它,也会作为Begin开头的API传入的回调函数的参数iAsyncResult.AsyncState //获取Begin开头的API传入的 作为回调方法的参数 的值iAsyncResult.AsyncWaitHandle //设置Begin开头的API返回的IAsyncResult的AsyncWaitHandle属性,可以让执行异步方法的线程卡住一段时间socket.BeginAccept() //异步监听客户端连入方法,传入回调函数和回调函数的参数socket.EndAccept() //结束异步监听客户端连入方法,传入回调函数的参数,返回连 ...
UN2L7——实现心跳消息
UN2L7——实现心跳消息
心跳消息
所谓心跳消息,就是在长连接中,客户端和服务端之间定期发送的一种特殊的数据包,用于通知对方自己还在线,以确保长连接的有效性
由于其发送的时间间隔往往是固定的持续的,就像是心跳一样一直存在,所以我们称之为心跳消息
心跳消息是长连接项目中必备的一套逻辑规则,通过它可以帮助我们在服务器端及时的释放掉失效的socket
可以有效避免当客户端非正常关闭时,服务器端不能及时判断连接已断开
为什么需要心跳消息
避免非正常关闭客户端时,服务器无法正常收到关闭连接消息,通过心跳消息我们可以自定义超时判断,
如果超时没有收到客户端消息,证明客户端已经断开连接
避免客户端长期不发送消息,防火墙或者路由器会断开连接,我们可以通过心跳消息一直保持活跃状态
实现心跳消息
首先声明一个不包括消息体的心跳消息
1234567891011121314151617181920212223242526public class HeartMessage : BaseMessage{ public override int GetBytesNum() { ...
UN2L6——客户端主动断开连接
UN2L6——客户端主动断开连接
本章代码关键字
1socket.Disconnect() //主动和服务器端断开连接方法,让服务器发现客户端主动断联不能只使用该方法
当前存在的问题
目前在客户端主动退出时,我们会调用socket的ShutDown和Close方法
但是通过调用这两个方法后,服务器端无法得知客户端已经主动断开
解决目前断开不及时的问题
客户端可以通过Disconnect方法主动和服务器端断开连接
服务器端可以通过Conected属性判断连接状态决定是否释放Socket
但是由于服务器端Conected变量表示的是上一次收发消息是否成功,所以服务器端无法准确判断客户端的连接状态
因此,我们需要自定义一条退出消息,用于准确断开和客户端之间的连接
客户端尝试使用Disconnect方法主动断开连接
Socket当中有一个专门在客户端使用的方法,Disconect方法,客户端调用该方法和服务器端断开连接
看是否是因为之前直接Close而没有调用Disconet造成服务器端无法及时获取状态
主要修改的逻辑:
客户 ...
UN2L5——分包、黏包
UN2L5——分包、黏包
分包、黏包
分包、黏包指在网络通信中由于各种因素(网络环境、API规则等)造成的消息与消息之间出现的两种状态
分包:一个消息分成了多个消息进行发送
黏包:一个消息和另一个消息黏在了一起
注意:分包和黏包可能同时发生
如何解决分包、黏包的问题
处理分包、黏包问题首先要了解什么是分包和黏包,解决该问题的逻辑实现的写法可能有很多种,我们采用最节约性能的方式解决问题就行
现在的处理:
我们收到的消息都是以字节数组的形式在程序中体现,目前我们的处理规则是默认传过来的消息就是正常情况
前4个字节是消息ID,后面的字节数组全部用来反序列化
如果出现分包、黏包会导致我们反序列化报错,因为数据可能不完整
思考:那么通过接收到的字节数组我们应该如何判断收到的字节数组处于以下状态
正常
分包
黏包
突破点:如何判断一个消息没有出现分包或者黏包呢?
答案:就是消息长度
我们可以如同处理 区分消息类型 的逻辑一样,为消息添加头部,头部记录消息的长度
当我们接收到消息时,通过消息长度来判断是否分包、黏包
对消息进行拆分处理、合并处理,我们每次只处理完整的消息
实 ...