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 = ;
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 = ;
int dataleft = size;
byte[] data = new byte[size];
int recv;
while (total < size)
{
recv = s.Receive(data, total, dataleft, SocketFlags.None);
if (recv == )
{
data = null;
break;
} total += recv;
dataleft -= recv;
}
return data;
} public static int SendVarData(Socket s, byte[] data)
{
int total = ;
int size = data.Length;
int dataleft = size;
int sent;
byte[] datasize = new byte[]; 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 ; }
} public static byte[] ReceiveVarData(Socket s)
{
int total = ;
int recv;
byte[] datasize = new byte[];
recv = s.Receive(datasize, , , SocketFlags.None);
int size = BitConverter.ToInt32(datasize, );
int dataleft = size;
byte[] data = new byte[size];
while (total < size)
{
recv = s.Receive(data, total, dataleft, SocketFlags.None);
if (recv == )
{
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个排队连接请求
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 = ;
while (true)
{ byte[] data = TransferFiles.ReceiveVarData(client);
if (data.Length == )
{
break;
}
else
{
SendedCount++;
//将接收到的数据包写入到文件流对象
MyFileStream.Write(data, , 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 = ; //包的数量
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 = ; i < PacketCount; i++)
{
//从文件流读取数据并填充数据包
EzoneStream.Read(data, , data.Length);
//发送数据包
if (TransferFiles.SendVarData(client, data) == )
{
isCut = true;
return false;
break;
} } //如果还有多余的数据包,则应该发送完毕!
if (LastDataPacket != )
{
data = new byte[LastDataPacket];
EzoneStream.Read(data, , data.Length);
TransferFiles.SendVarData(client, data);
} //关闭套接字
client.Close();
//关闭文件流
EzoneStream.Close();
if (!isCut)
{
return true;
}
return false;
}
}
}

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

  1. Socket传输大文件(发送与接收)

    下载 Client using System; using System.Collections.Generic; using System.Linq; using System.Text; usin ...

  2. 利用Socket进行大文件传输

    分类: WINDOWS 最近接触到利用socket进行大文件传输的技术,有些心得,与大家分享.首先看看这个过程是怎么进行的(如下图):      所以,我们需要三个socket在窗体加载的时候初始化: ...

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

    基于RMI服务传输大文件,分为上传和下载两种操作,需要注意的技术点主要有三方面,第一,RMI服务中传输的数据必须是可序列化的.第二,在传输大文件的过程中应该有进度提醒机制,对于大文件传输来说,这点很重 ...

  4. linux传输大文件

    http://dreamway.blog.51cto.com/1281816/1151886 linux传输大文件

  5. C# 的 WCF文章 消息契约(Message Contract)在流(Stream )传输大文件中的应用

    我也遇到同样问题,所以抄下做MARK http://www.cnblogs.com/lmjq/archive/2011/07/19/2110319.html 刚做完一个binding为netTcpBi ...

  6. WCF 用netTcpbinding,basicHttpBinding 传输大文件

    问题:WCF如何传输大文件 方案:主要有几种绑定方式netTcpbinding,basicHttpBinding,wsHttpbinding,设置相关的传输max消息选项,服务端和客户端都要设置,tr ...

  7. 使用QQ传输大文件

    现在在公网上能传输大文件并且稳定支持断点续传的软件非常少了,可以使用qq来做这件事. qq传输单个文件有时候提示不能超过4g有时候提示不能超过60g,没搞明白具体怎么样. 可以使用qq的传输文件夹功能 ...

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

    TCP协议传输大文件读取时候的问题 大文件传不完的bug 我们在定义的时候定义服务端每次文件读取大小为10240, 客户端每次接受大小为10240 我们想当然的认为客户端每次读取大小就是10240而把 ...

  9. 基于socket实现大文件上传

    import socket 1.客户端: 操作流程: 先拿到文件--->获取文件大小---->创建字典 1.制作表头 header  如何得到 他是一个二进制字符串 序列化得到 字典字符串 ...

随机推荐

  1. input 类型为number型时,maxlength不生效?

    input 类型为number型时,maxlength不生效? 可以加oninput属性来控制最大长度:<input id="numInput" type="num ...

  2. PHP中检测ajax请求的代码例子

    多数情况下,基于JavaScript 的Js框架如jquery.Mootools.Prototype等,在发出Ajax请求指令时,都会发送额外的 HTTP_X_REQUESTED_WITH 头部信息, ...

  3. .net转php laraval框架学习系列(一) 环境搭建

    之前也没写过什么博客,可能文章结构比较混乱,想到那写到哪. 主要是把自己学习中的经验写下来. 为什么选择laravel框架,是因为laravel框架目前是Php最流行的框架,深入研究后发现和asp.n ...

  4. PHP学习系列(1)——字符串处理函数(4)

    16.hebrevc() 函数把希伯来文本从右至左的流转换为左至右的流.它也会把新行 (\n) 转换为 <br />.只有 224 至 251 之间的 ASCII 字符,以及标点符号受到影 ...

  5. php cgi 与 cli 区别

    以CGI方式运行时,web server将用户请求以消息的方式转交给PHP独立进程,PHP与web服务之间无从属关系:CLI则是命令行接口,用于在操作系统命令行模式下执行PHP,比如可以直接在win的 ...

  6. 深入理解querySelector(All)

          querySelector和querySelectorAll同属于Selectors API Level 1规范,该规范早在2006年就已经开始发展,并在2007年10月形成querySe ...

  7. Android 获取网络链接类型

    /** * 获取当前网络类型 * @return 0:没有网络 1:WIFI网络 2:WAP网络 3:NET网络 */ public int getNetworkType() { int netTyp ...

  8. 无法关闭的QT程序(覆盖closeEvent,新建QProcess并脱离关系)

    做一个无法关闭的QT程序(想关闭时要在任务管理器里关闭),看似很难, 其实它并不难,只要让程序在关闭时启动它自身就可以了. 上代码: #include <QtGui> class Temp ...

  9. Android Canvas.drawText方法中的坐标参数的正确解释

    摘要 canvas.drawText(www.jcodecraeer.com, x, y, paint); x和y参数是指定字符串中心的坐标吗?还是左上角的坐标?这个问题的直观印象应该是左上角的坐标, ...

  10. Linux企业级项目实践之网络爬虫(27)——多路IO复用

    与多线程和多进程相比,I/O多路复用的最大优势是系统开销小,系统不需要建立新的进程或者线程,也不必维护这些线程和进程. 主要应用: (1)客户程序需要同时处理交互式的输入和服务器之间的网络连接 (2) ...