前段时间公司项目中遇着需要做文件的远程传输,场景是用户通过网页选择一些文件,然后提交请求到服务器,同时把请求标识传递给本机的TCP文件传输端;服务器收到请求后在服务器端创建任务生成保存文件的路径同时通知文件传输端开始传文件到服务器,当时是同事用C++写的传输端,于是便想何不用NET来实现呢,本来服务端的大部分程序和客户端程序都是用NET写的,于是便有了这篇文章。小生一直是做web开发的,对WinForm技术不胜熟悉,如有不妥还请拍砖。
在NET框架下可以方便的使用tcplistener和tcpclient两个类来实现tcp编程,而无需直接操作socket,这也是这两个类方便的地方。对于tcplistener可以理解是用在服务端的,仅需要设置一个监听端口即可,如
var listener = new TcpListener(9000);//监听9000端口
然后调用 Start方法开始监听:
listener.Start(10);//挂起队列最大长度10个
再然后就是等待客户端的接入了,通常可以用一个无限循环来接受不断请求的客户端
while (true)
{
if (listener.Pending())//异步接受一个请求
{
var client= listener.AcceptTcpClient();
//现在就可以使用client,爱干嘛干嘛吧
}
}
在这里,为了实现多个客户端同时访问通常会使用异步的BeginAcceptTcpClient来接受客户端请求
有了client,通过GetStream方法就得到当前的网络流,使用Write,Read方法即可进行数据写入和读取。
对于tcpclient,使用的时候您需要告诉他去连接哪台计算机的哪个端口(使用Endpoint来表示),然后调用Connect方法,就像下面这样
var _endPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"),9000);
var client = new TcpClient();
client.Connect(_endPoint);
如果服务端是开启的,这样就能连接上了。
下一步就是读取或者发送数据到服务端了,同样可以使用GetStream方法获取到网络流,使用Write,Read方法即可进行数据写入和读取。
这些操作都是基于流进行的,因此数据本身不具有结构,比如对于一个操作,服务端需要知道操作名和操作数据,这两个东西放在流里一起发送过去没有人会认识,这就要求服务端和客户端在传递数据的时候遵循一致的数据结构,比如使用这样的 method:getname#parms:ky
现在介绍下本篇附带的实例:
在服务端启动的时候会要求用户输入一个共享的文件夹路径,然后启动服务,这个服务会提供给客户端这个文件夹下的图片文件列表,同时也可以让客户端下载图片;
客户端启动时要求用户输入一个服务端的地址,然后点击getfilelist来获取远程文件夹的文件列表,然后选择一个文件即可下载这个文件到本地。
部分截图:
服务端
客户端
源文件下载