C# Socket传输大文件

1.基础类TransferFiles,client和server都需要


using System;
using System.Collections.Generic;
using System.Text;

using System.Net;
using System.Net.Sockets;
using System.Windows.Forms;

namespace Server
{
public class TransferFiles
{
public static int SendData(Socket s, byte[] data)
{
int total = 0;
int size = data.Length;
int dataleft = size;
int sent;

while (total < size)
{
sent = s.Send(data, total, dataleft, SocketFlags.None);
total += sent;
dataleft -= sent;
}

return total;
}

public static byte[] ReceiveData(Socket s, int size)
{
int total = 0;
int dataleft = size;
byte[] data = new byte[size];
int recv;
while (total < size)
{
recv = s.Receive(data, total, dataleft, SocketFlags.None);
if (recv == 0)
{
data = null;
break;
}

total += recv;
dataleft -= recv;
}
return data;
}

public static int SendVarData(Socket s, byte[] data)
{
int total = 0;
int size = data.Length;
int dataleft = size;
int sent;
byte[] datasize = new byte[4];

try
{
datasize = BitConverter.GetBytes(size);
sent = s.Send(datasize);

while (total < size)
{
sent = s.Send(data, total, dataleft, SocketFlags.None);
total += sent;
dataleft -= sent;
}

return total;
}
catch
{
return 3;

}
}

public static byte[] ReceiveVarData(Socket s)
{
int total = 0;
int recv;
byte[] datasize = new byte[4];
recv = s.Receive(datasize, 0, 4, SocketFlags.None);
int size = BitConverter.ToInt32(datasize, 0);
int dataleft = size;
byte[] data = new byte[size];
while (total < size)
{
recv = s.Receive(data, total, dataleft, SocketFlags.None);
if (recv == 0)
{
data = null;
break;
}
total += recv;
dataleft -= recv;
}
return data;
}
}
}

2.Server端


using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.IO;
using System.Configuration;

namespace Server
{
public static class FileServer
{
private static Socket serverSocket;
public static void Init()
{
//服务器IP地址
IPAddress ip = IPAddress.Parse(ConfigurationManager.AppSettings["ListenIP"]);
int myProt = Convert.ToInt32(ConfigurationManager.AppSettings["ListenFilePort"]);
serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
serverSocket.Bind(new IPEndPoint(ip, myProt)); //绑定IP地址:端口
serverSocket.Listen(10); //设定最多10个排队连接请求
Console.WriteLine("启动监听{0}成功", serverSocket.LocalEndPoint.ToString());
//通过Clientsoket发送数据
Thread myThread = new Thread(ListenClientConnect);
myThread.Start();
}
public static void Exit()
{
serverSocket.Close();
serverSocket = null;
}
private static void ListenClientConnect()
{
while (true)
{
if (serverSocket != null)
{
try
{
Socket clientSocket = serverSocket.Accept();
Thread receiveThread = new Thread(Create);
receiveThread.Start(clientSocket);
}
catch
{
break;
}
}
}
}
public static void Create(object clientSocket)
{
Socket client = clientSocket as Socket;
//获得客户端节点对象
IPEndPoint clientep = (IPEndPoint)client.RemoteEndPoint;

//获得[文件名]
string SendFileName = System.Text.Encoding.Unicode.GetString(TransferFiles.ReceiveVarData(client));

//检查是否使用本地媒体库
if (SocketServer.useLocal)
{
//关闭套接字
client.Close();
return;
}

//获得[包的大小]
string bagSize = System.Text.Encoding.Unicode.GetString(TransferFiles.ReceiveVarData(client));

//获得[包的总数量]
int bagCount = int.Parse(System.Text.Encoding.Unicode.GetString(TransferFiles.ReceiveVarData(client)));

//获得[最后一个包的大小]
string bagLast = System.Text.Encoding.Unicode.GetString(TransferFiles.ReceiveVarData(client));

string fullPath = Path.Combine(Environment.CurrentDirectory,SendFileName);
//创建一个新文件
FileStream MyFileStream = new FileStream(fullPath, FileMode.Create, FileAccess.Write);

//已发送包的个数
int SendedCount = 0;
while (true)
{

byte[] data = TransferFiles.ReceiveVarData(client);
if (data.Length == 0)
{
break;
}
else
{
SendedCount++;
//将接收到的数据包写入到文件流对象
MyFileStream.Write(data, 0, data.Length);
//显示已发送包的个数

}
}
//关闭文件流
MyFileStream.Close();
//关闭套接字
client.Close();
SocketServer.pForm.ShowMessageBox(SendFileName + "接收完毕!");
}
}
}

3.Client端


using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Diagnostics;

namespace Client
{
public static class FileClient
{
public static bool SendFile(string IP,int Port,string fullPath)
{
//创建一个文件对象
FileInfo EzoneFile = new FileInfo(fullPath);
//打开文件流
FileStream EzoneStream = EzoneFile.OpenRead();

//包的大小
int PacketSize = 10000;

//包的数量
int PacketCount = (int)(EzoneStream.Length / ((long)PacketSize));

//最后一个包的大小
int LastDataPacket = (int)(EzoneStream.Length - ((long)(PacketSize * PacketCount)));

//指向远程服务端节点
IPEndPoint ipep = new IPEndPoint(IPAddress.Parse(IP), Port);

//创建套接字
Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

//连接到发送端
try
{
client.Connect(ipep);
}
catch
{
Debug.WriteLine("连接服务器失败!");
return false;
}
//获得客户端节点对象
IPEndPoint clientep = (IPEndPoint)client.RemoteEndPoint;

//发送[文件名]到客户端
TransferFiles.SendVarData(client, System.Text.Encoding.Unicode.GetBytes(EzoneFile.Name));

//发送[包的大小]到客户端
TransferFiles.SendVarData(client, System.Text.Encoding.Unicode.GetBytes(PacketSize.ToString()));

//发送[包的总数量]到客户端
TransferFiles.SendVarData(client, System.Text.Encoding.Unicode.GetBytes(PacketCount.ToString()));

//发送[最后一个包的大小]到客户端
TransferFiles.SendVarData(client, System.Text.Encoding.Unicode.GetBytes(LastDataPacket.ToString()));

bool isCut = false;
//数据包
byte[] data = new byte[PacketSize];
//开始循环发送数据包
for (int i = 0; i < PacketCount; i++)
{
//从文件流读取数据并填充数据包
EzoneStream.Read(data, 0, data.Length);
//发送数据包
if (TransferFiles.SendVarData(client, data) == 3)
{
isCut = true;
return false;
break;
}

}

//如果还有多余的数据包,则应该发送完毕!
if (LastDataPacket != 0)
{
data = new byte[LastDataPacket];
EzoneStream.Read(data, 0, data.Length);
TransferFiles.SendVarData(client, data);
}

//关闭套接字
client.Close();
//关闭文件流
EzoneStream.Close();
if (!isCut)
{
return true;
}
return false;
}
}
}

C# Socket传输大文件

时间: 2024-10-10 16:31:52

C# Socket传输大文件的相关文章

个人第一个开源分布式项目distributeTemplate的实现三 网络通讯netty传输大文件

今天 我将讲讲网络通讯,这里我初始版本 由于采用的事Netty框架  所以 这里讲网络Netty在我们这里是怎么使用的,下周开始添加rpc lucene内容了 实现之后的0.2 0.3版本,后面将会去掉netty依赖 采用原生的NIO2 (aio) 异步非阻塞方式 实现自己网络通讯,也就是说 这部分可能会实现一个简单的但是比netty精简高效的网络框架,后期做出来 可能会单独开一个分支开源出来,netty说白了 就是 事件驱动 以及 NIO 加一些协议 以及 异常 处理,废话不多说了. 我最近

基于RMI服务传输大文件的完整解决方案

基于RMI服务传输大文件,分为上传和下载两种操作,需要注意的技术点主要有三方面,第一,RMI服务中传输的数据必须是可序列化的.第二,在传输大文件的过程中应该有进度提醒机制,对于大文件传输来说,这点很重要,因为大文件的传输时间周期往往比较长,必须实时告知用户大文件的传输进度.第三,针对大文件的读取方式,如果采用一次性将大文件读取到byte[]中是不现实的,因为这将受制于JVM的可用内存,会导致内存溢出的问题. 笔者实验的基于RMI服务传输大文件的解决方案,主要就是围绕以上三方面进行逐步解决的.下面

OpenAdaptor1——基于webservice传输大文件

<span style="font-family:Arial, Helvetica, sans-serif;BACKGROUND-COLOR: rgb(255,255,255)">OpenAdaptor支持XFire和CXF开发的webservice,所以开发CXF webservice,基于myeclipse开发比较容易.参照网上webrvice传输大文件示例修改 http://blog.csdn.net/kongxx/article/details/7540930<

远程传输大文件使用什么平台好呢?

远程传输大文件使用什么平台好呢?小文件倒是还可以通过QQ这样的方式进行传输,但是它对传输文件的大小有所限制,传输大文件就行不通了. 远程传输大文件使用什么平台好呢?传输大文件一个是要求传输稳定,不能说传了一点就断了,人又不可能一直盯着看是不是正常传输,这会造成传输时间的浪费.再一个要求文件传输的速度不能太慢,既然是大文件传输,速度很慢可能就要花好几个小时,甚至一整天,这会延误文件的传达. 我平时是使用网盘进行大文件的传输,网盘传输的速度比一般的通讯工具要更加快,也更加稳定,还没有文件的限制. 比

TCP协议传输大文件读取时候的问题

TCP协议传输大文件读取时候的问题 大文件传不完的bug 我们在定义的时候定义服务端每次文件读取大小为10240, 客户端每次接受大小为10240 我们想当然的认为客户端每次读取大小就是10240而把客户端的读下来的文件想当然大小每一次都加上10240 而实际上服务端发送文件send每次发送不一定是一次性把10240的文件传送完,可能分了好几次进行发送至缓冲区这我们实际文件大小就不一定是10240 解决办法: 1.对于每次服务端所发送的文件内容及大小都发送给客户端,让客户端一一对应读取 2.实时

rsync增量传输大文件优化技巧

问题 rsync用来同步数据非常的好用,特别是增量同步.但是有一种情况如果不增加特定的参数就不是很好用了.比如你要同步多个几十个G的文件,然后网络突然断开了一下,这时候你重新启动增量同步.但是发现等了好久都没有进行数据传输,倒是机器的IO一直居高不下. 原因 rsync具体的增量同步算法不太清楚.根据它的表现来看,可能在增量同步已经存在的一个文件时,会校验已传输部分数据是否已源文件一致,校验完成才继续增量同步这个文件剩下的数据.所以如果对一个大文件以这样的算法来增量同步是非常花时间并且占用IO资

Android应用开发之使用Socket进行大文件断点上传续传

http://www.linuxidc.com/Linux/2012-03/55567.htm http://blog.csdn.net/shimiso/article/details/8529633/ 在Android中上传文件可以采用HTTP方式,也可以采用Socket方式,但是HTTP方式不能上传大文件,这里介绍一种通过Socket方式来进行断点续传的方式,服务端会记录下文件的上传进度,当某一次上传过程意外终止后,下一次可以继续上传,这里用到的其实还是J2SE里的知识. 这个上传程序的原理

怎么解决FTP传输大文件严重丢包的问题?

通过FTP方式把公司总部的大体量文件传输到国内多地,或者发往国外,经常遇到长距离网络不可避免的时延丢包及跨运营商的情况.如何解决这个问题? 其实不仅是大文件,网络上传输的各种内容,大多数都需要解决丢包和损坏问题.只是对于大文件传输,丢包和损坏的情况可能更明显. 常用的传输方式有两种:TCP和UDP. 传统FTP是使用TCP作为传输协议的.TCP的优点是可靠稳定,在传输数据之前,会有三次握手来建立连接.其缺点是数据传输慢,效率低,占用系统资源高,易被***.因此,使用TCP在低时延和低丢包的网络环

怎么远程传输大文件?

在日常工作中,我们常常会遇到将电脑的文件,特别是大文件资料进行传输,比如设计稿件,软件开发包,视频素材等等大文件资料进行传输发送.虽然网络通信技术不断发展,对大数据量,高频次,远距离的文件传输成为我们工作中常常遇到的问题.常用的QQ文件传输,微信发送,邮箱,FTP等常规方式,都要面对一方发送,一方接收,或者提前上传到服务器,然后接收方下载,同时也收到附件大小的限制,导致工作效率大大降低.传统的传输方式主要分为:http与ftp.我们常用的邮件发送就是http的一种,其主要是便捷,简单.然后很多h