Socket传输大文件(发送与接收)
Client
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.IO;
using System.Windows.Forms; namespace SocketClient
{
class Program
{
[STAThread]
static void Main(string[] args)
{
SocketClient();
}
public static string serverIp = "127.0.0.1";//设置服务端IP
public static int serverPort = ;//服务端端口
public static Socket socketClient;//定义socket
public static Thread threadClient;//定义线程
public static byte[] result = new byte[];//定义缓存
public static void SocketClient()
{
socketClient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);//创建一个socket的对象
IPAddress ip = IPAddress.Parse(serverIp);//获取服务器IP地址
IPEndPoint point = new IPEndPoint(ip, serverPort);//获取端口
try
{
socketClient.Connect(point);//链接服务器IP与端口
Console.WriteLine("连接服务器中....."); }
catch (Exception)
{
Console.WriteLine("与服务器链接失败!!!");
return;
}
Console.WriteLine("与服务器链接成功!!!");
try
{
Thread.Sleep(); //等待1秒钟
//通过 socketClient 向服务器发送数据
string sendMessage = "已成功接到SocketClient发送的消息";//发送到服务端的内容
byte[] send = Encoding.UTF8.GetBytes(sendMessage);//Encoding.UTF8.GetBytes()将要发送的字符串转换成UTF8字节数组
byte[] SendMsg = new byte[send.Length + ];//定义新的字节数组
SendMsg[] = ;//将数组第一位设置为0,来表示发送的是消息数据
Buffer.BlockCopy(send, , SendMsg, , send.Length);//偏移复制字节数组
socketClient.Send(SendMsg); //将接受成功的消息返回给SocketServer服务器
Console.WriteLine("发送完毕:{0}", sendMessage); }
catch
{
socketClient.Shutdown(SocketShutdown.Both);//禁止Socket上的发送和接受
socketClient.Close();//关闭Socket并释放资源
}
//打开文件
OpenFileDialog ofd = new OpenFileDialog();
ofd.Title = "选择要传的文件";
ofd.InitialDirectory = @"E:\IVS\Down";
//ofd.Filter = "文本文件|*.txt|图片文件|*.jpg|视频文件|*.avi|所有文件|*.*";
ofd.ShowDialog();
//得到选择文件的路径
string filePath = ofd.FileName;//获取文件的完整路径
Console.WriteLine("发送的文件路径为:"+filePath);
using (FileStream fsRead = new FileStream(filePath, FileMode.OpenOrCreate, FileAccess.Read))
{
//1. 第一步:发送一个文件,表示文件名和长度,让客户端知道后续要接收几个包来重新组织成一个文件
string fileName = Path.GetFileName(filePath);
Console.WriteLine("发送的文件名是:" + fileName);
long fileLength = fsRead.Length;//文件长度
Console.WriteLine("发送的文件长度为:"+fileLength);
string totalMsg = string.Format("{0}-{1}", fileName, fileLength);
byte[] buffer = Encoding.UTF8.GetBytes(totalMsg);
byte[] newBuffer = new byte[buffer.Length + ];
newBuffer[] = ;
Buffer.BlockCopy(buffer, , newBuffer, , buffer.Length);
socketClient.Send(newBuffer);//发送文件前,将文件名和长度发过去
//2第二步:每次发送一个1MB的包,如果文件较大,则会拆分为多个包
byte[] Filebuffer = new byte[ * * ];//定义1MB的缓存空间
int readLength = ; //定义读取的长度
bool firstRead = true;
long sentFileLength = ;//定义发送的长度
while ((readLength = fsRead.Read(buffer, , buffer.Length)) > && sentFileLength < fileLength)
{
sentFileLength += readLength;
//第一次发送的字节流上加个前缀1
if (firstRead)
{
byte[] firstBuffer = new byte[readLength + ];
firstBuffer[] = ;//标记1,代表为文件
Buffer.BlockCopy(buffer, , firstBuffer, , readLength);
socketClient.Send(firstBuffer, , readLength + , SocketFlags.None);
Console.WriteLine("第一次读取数据成功,在前面添加一个标记");
firstRead = false;
continue;
}
socketClient.Send(buffer, , readLength, SocketFlags.None);
Console.WriteLine("{0}: 已发送数据:{1}/{2}", socketClient.RemoteEndPoint, sentFileLength, fileLength);
}
fsRead.Close();
Console.WriteLine("发送完成");
}
Console.ReadLine();
}
} }
Server
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.IO;
using System.Windows.Forms; namespace SocketServer
{
class Program
{
[STAThread]
static void Main(string[] args)
{
SocketServer();
}
public static string serverIp = "127.0.0.1";//设置服务端IP
public static int serverPort = ;//服务端端口
public static Socket socketServer;//定义socket
public static Thread threadWatch;//定义线程
public static byte[] result = new byte[ * * ];//定义缓存
//public static string fileName;//获取文件名
public static string filePath = "";//存储保存文件的路径
public static void SocketServer()
{
socketServer = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);//创建一个socket的对象
IPAddress ip = IPAddress.Parse(serverIp);//获取服务器IP地址
IPEndPoint point = new IPEndPoint(ip, serverPort);//获取端口
try
{
socketServer.Bind(point);//绑定IP地址及端口
}
catch (Exception ex)
{
Console.WriteLine("绑定IP时出现异常:" + ex.Message);
return;
}
socketServer.Listen();//开启监听并设定最多10个排队连接请求
threadWatch = new Thread(WatchConnect);//创建一个监听进程
threadWatch.IsBackground = true;//后台启动
threadWatch.Start();//运行
Console.WriteLine("服务器{0}监听启动成功!", socketServer.LocalEndPoint.ToString());
Console.ReadLine();
}
public static void WatchConnect()
{
while (true)
{
Socket watchConnect = socketServer.Accept();//接收连接并返回一个新的Socket
watchConnect.Send(Encoding.UTF8.GetBytes("服务器连接成功"));//在客户端显示"服务器连接成功"提示
Thread threadwhat = new Thread(ReceiveMsg);//创建一个接受信息的进程
threadwhat.IsBackground = true;//后台启动
threadwhat.Start(watchConnect);//有传入参数的线程
}
}
public static DateTime GetTime()
{
DateTime now = new DateTime();
now = DateTime.Now;
return now;
}
public static void ReceiveMsg(object watchConnect)
{
Socket socketServer = watchConnect as Socket;
long fileLength = ;//文件长度
string recStr = null;//文件名
while (true)
{
int firstRcv = ;
byte[] buffer = new byte[ * * ];
try
{
//获取接受数据的长度,存入内存缓冲区,返回一个字节数组的长度
if (socketServer != null) firstRcv = socketServer.Receive(buffer);
if (firstRcv > )//大于0,说明有东西传过来
{
if (buffer[] == )//0对应文字信息
{
string recMsg = Encoding.UTF8.GetString(buffer, , firstRcv - );
Console.WriteLine("客户端接收到信息:" + socketServer.LocalEndPoint.ToString() + "\r\n" + GetTime() + "\r\n" + recMsg + "\r\n");
} if (buffer[] == )//1对应文件信息
{
SaveFileDialog sfDialog = new SaveFileDialog();//创建SaveFileDialog实例
string spath = @"E:\存放";//制定存储路径
string savePath = Path.Combine(spath, recStr);//获取存储路径及文件名
int rec = ;
long recFileLength = ;
bool firstWrite = true;
using (FileStream fs = new FileStream(savePath, FileMode.Create, FileAccess.Write))
{
while (recFileLength < fileLength)
{
if (firstWrite)
{
fs.Write(buffer, , firstRcv - );
fs.Flush();
recFileLength += firstRcv - ;
firstWrite = false;
}
else
{
rec = socketServer.Receive(buffer);
fs.Write(buffer, , rec);
fs.Flush();
recFileLength += rec;
}
Console.WriteLine("{0}: 已接收数据:{1}/{2}", socketServer.RemoteEndPoint, recFileLength, fileLength);
}
fs.Close();
}
Console.WriteLine("保存成功!!!!");
}
if (buffer[] == )//2对应文件名字和长度
{
string fileNameWithLength = Encoding.UTF8.GetString(buffer, , firstRcv - );
recStr = fileNameWithLength.Split('-').First();//获取文件名
Console.WriteLine("接收到的文件名为:" + recStr);
fileLength = Convert.ToInt64(fileNameWithLength.Split('-').Last());//获取文件长度
Console.WriteLine("接收到的文件长度为:" + fileLength);
}
}
}
catch (Exception ex)
{
Console.WriteLine("系统异常..." + ex.Message);
break;
}
} //while (true)
//{
// int num = -1;//初始化num
// string reveiceName;//定义字符串
// try
// {
// num = socketClient.Receive(result);//获取客户端信息
// reveiceName = Encoding.UTF8.GetString(result, 0, num);//把从0到num的字节变成String
// }
// catch (SocketException ex)
// {
// Console.WriteLine("异常:" + ex.Message + ", RemoteEndPoint: " + socketClient.RemoteEndPoint.ToString());
// break;
// }
// catch (Exception ex)
// {
// Console.WriteLine("异常:" + ex.Message);
// break;
// } //while (true)
//{ //try
//{
// /// <summary>
// /// 存储大文件的大小
// /// </summary>
// long length = 0;
// long recive = 0; //接收的大文件总的字节数
// while (true)
// {
// byte[] buffer = new byte[1024 * 1024];
// int r = socketClient.Receive(buffer);
// Console.WriteLine("接受到的字符长度" + r);
// if (r == 0)
// {
// break;
// }
// Console.WriteLine("第二次的length长度为:" + length);
// if (length > 0) //判断大文件是否已经保存完
// {
// //保存接收的文件
// using (FileStream fsWrite = new FileStream(filePath, FileMode.Append, FileAccess.Write))
// {
// Console.WriteLine("-----------------11111111111111111111111-----------------------------");
// fsWrite.Write(buffer, 0, r);
// length -= r; //减去每次保存的字节数
// Console.WriteLine("{0}: 已接收:{1}/{2}", socketClient.RemoteEndPoint, recive - length, recive);
// if (length <= 0)
// {
// Console.WriteLine(socketClient.RemoteEndPoint + ": 接收文件成功");
// }
// continue;
// }
// }
// if (buffer[0] == 0) //如果接收的字节数组的第一个字节是0,说明接收的字符串信息
// {
// string strMsg = Encoding.UTF8.GetString(buffer, 1, r - 1);
// Console.WriteLine("*****************0000000000000000000000*********************");
// Console.WriteLine(socketClient.RemoteEndPoint.ToString() + ": " + strMsg);
// }
// else if (buffer[0] == 1) //如果接收的字节数组的第一个字节是1,说明接收的是文件
// {
// Console.WriteLine("++++++++++++++111111111111111111111+++++++++++++++++++");
// length = int.Parse(Encoding.UTF8.GetString(buffer, 1, r - 1));
// recive = length;
// Console.WriteLine("接收到的字节长度是多少呢:?" + length);
// SaveFileDialog sfd = new SaveFileDialog();
// sfd.Title = "保存文件";
// sfd.InitialDirectory = @"C:\Users\Administrator\Desktop";
// //sfd.Filter = "文本文件|*.txt|图片文件|*.jpg|视频文件|*.avi|所有文件|*.*";
// //如果没有选择保存文件路径就一直打开保存框
// SaveFileDialog save = new SaveFileDialog();//创建SaveFileDialog实例
// string spath = @"C:\Users\admin\Desktop";//制定存储路径
// filePath = Path.Combine(spath, fileName);//获取存储路径及文件名
// }
// }
//}
//catch { } //} //try
//{
// if (reveiceName[0] == 0)//判断数组第一个值,如果为0则说明传的是信息
// {
// fileName = Encoding.UTF8.GetString(result, 1, num - 1);//提取字节信息并转换成String
// Console.WriteLine("接收客户端的消息:{0}", fileName);
// }
// if (reveiceName[0] == 1)//判断数组第一个值,如果为1则说明传的是文件
// {
// SaveFileDialog save = new SaveFileDialog();//创建SaveFileDialog实例
// string spath = @"C:\Users\admin\Desktop";//制定存储路径
// string fullPath = Path.Combine(spath, fileName);//获取存储路径及文件名
// //FileStream filesave = new FileStream(fullPath, FileMode.Create, FileAccess.Write);//创建文件流,用来写入数据
// //filesave.Write(result, 1, num - 1);//将数据写入到文件中
// //filesave.Close();
// //Console.WriteLine("保存成功!!!");
// //**************************************************************************************************
// while (true)
// {
// byte[] buffer = new byte[1024 * 1024];
// int r = socketClient.Receive(buffer);
// Console.WriteLine("从客户端接收到的字节数:"+r);
// //string leng = Encoding.UTF8.GetString(buffer, 1, r - 1);
// int recive = r - 1;
// //Console.WriteLine(leng);
// //long recive = int.Parse(leng);
// //long recive = Convert.ToInt64(Encoding.UTF8.GetString(buffer, 1, r - 1));
// Console.WriteLine("总接受字节数:" + recive);
// long length = recive;
// Console.WriteLine("*******************************************");
// if (length > 0)
// {
// using (FileStream fsWrite = new FileStream(fullPath, FileMode.Append, FileAccess.Write))
// {
// Console.WriteLine("---------*************--------------");
// fsWrite.Write(buffer,1, r-1);
// length -= r; //减去每次保存的字节数
// Console.WriteLine("剩余接受字节数:"+length);
// Console.WriteLine(string.Format("{0}: 已接收:{1}/{2}", socketClient.RemoteEndPoint, recive - length, recive));
// if (length <= 0)
// {
// Console.WriteLine(socketClient.RemoteEndPoint + ": 接收文件成功");
// }
// }
// }
// } // //long recive = 0; //接收的大文件总的字节数
// //while (true)
// //{
// // //byte[] buffer = new byte[1024 * 1024];
// // //int r = socketClient.Receive(buffer); // // if (num == 0)
// // {
// // break;
// // }
// // if (length > 0) //判断大文件是否已经保存完
// // {
// // //保存接收的文件
// // using (FileStream fsWrite = new FileStream(fullPath, FileMode.Append, FileAccess.Write))
// // {
// // fsWrite.Write(result, 1, num-1);
// // length -= num; //减去每次保存的字节数
// // Console.WriteLine(string.Format("{0}: 已接收:{1}/{2}", socketClient.RemoteEndPoint, recive-length, recive));
// // if (length <= 0)
// // {
// // Console.WriteLine(socketClient.RemoteEndPoint + ": 接收文件成功");
// // }
// // continue;
// // }
// // }
// }
//}
//catch (Exception ex)
//{ // Console.WriteLine(ex.Message);
//} //} }
}
}
Socket传输大文件(发送与接收)的更多相关文章
- C# Socket传输大文件
1.基础类TransferFiles,client和server都需要 using System; using System.Collections.Generic; using System.Tex ...
- 利用Socket进行大文件传输
分类: WINDOWS 最近接触到利用socket进行大文件传输的技术,有些心得,与大家分享.首先看看这个过程是怎么进行的(如下图): 所以,我们需要三个socket在窗体加载的时候初始化: ...
- 基于socket实现大文件上传
import socket 1.客户端: 操作流程: 先拿到文件--->获取文件大小---->创建字典 1.制作表头 header 如何得到 他是一个二进制字符串 序列化得到 字典字符串 ...
- 基于RMI服务传输大文件的完整解决方案
基于RMI服务传输大文件,分为上传和下载两种操作,需要注意的技术点主要有三方面,第一,RMI服务中传输的数据必须是可序列化的.第二,在传输大文件的过程中应该有进度提醒机制,对于大文件传输来说,这点很重 ...
- 使用QQ传输大文件
现在在公网上能传输大文件并且稳定支持断点续传的软件非常少了,可以使用qq来做这件事. qq传输单个文件有时候提示不能超过4g有时候提示不能超过60g,没搞明白具体怎么样. 可以使用qq的传输文件夹功能 ...
- TCP协议传输大文件读取时候的问题
TCP协议传输大文件读取时候的问题 大文件传不完的bug 我们在定义的时候定义服务端每次文件读取大小为10240, 客户端每次接受大小为10240 我们想当然的认为客户端每次读取大小就是10240而把 ...
- linux传输大文件
http://dreamway.blog.51cto.com/1281816/1151886 linux传输大文件
- C# 的 WCF文章 消息契约(Message Contract)在流(Stream )传输大文件中的应用
我也遇到同样问题,所以抄下做MARK http://www.cnblogs.com/lmjq/archive/2011/07/19/2110319.html 刚做完一个binding为netTcpBi ...
- WCF 用netTcpbinding,basicHttpBinding 传输大文件
问题:WCF如何传输大文件 方案:主要有几种绑定方式netTcpbinding,basicHttpBinding,wsHttpbinding,设置相关的传输max消息选项,服务端和客户端都要设置,tr ...
随机推荐
- 360网安学习笔记——Web安全原理与实践
网络安全 基本技能: 1.编程语言 2.计算机网络 3.操作系统 4.office 专业技能 1.web安全 2.网络安全 3.渗透测试 4.代码审计 能力提升 1.书籍 2.站点 3.安全平台 We ...
- C — 小知识
老是记错int与void*之间的转换,所以记录一个,顺便用一下一些宏.预处理... int与void*的转换.打印变量名: #include <stdio.h> // 打印变量名 #def ...
- js 字符串相关函数
https://www.jb51.net/article/74614.htm
- Flask程序相关配置加载的三种方式
方式一:从对象中加载配置 1.定义配置类,在配置类中添加相应的配置 2.通过app.config.from_object(配置类)进行加载 代码如下: from flask import Flask ...
- crm系统和e_store商场的比较总结
e_store用了:Java.Servlet.JSP.Oracle.JQuery.Mybatis,tomcat技术 crm用了 :Java.JSP.Oracle.JQuery,Mybatis,spri ...
- Checked exceptions: Java’s biggest mistake-检查型异常:Java最大的错误(翻译)
原文地址:http://literatejava.com/exceptions/checked-exceptions-javas-biggest-mistake/ 仅供参考,毕竟我四级都没过 Chec ...
- nacos集群配置
一. 环境准备 Nacos 依赖 java环境来运行.如果您是从代码开始构建并运行Nacos,还需要为此配置 Maven环境,请确保是在以下版本环境中安装使用: 64 bit OS,支持 Lin ...
- java 实现图片上传功能
1:jsp 页面上传图片按钮在这里我就写相关的代码 <div class="control-group"> <label class="control- ...
- jsp 防止表单多次提交
1:首先java 后台代码生成一个token,然后保存到jsp 页面的一个隐藏控件并且保存到set session中 */ @RequestMapping("/yuDengJi") ...
- 基本使用-ElasticSearch
基本使用-ElasticSearch 说明:本篇文章主要是通过springboot整合es的基本使用基础,详细了解的可以看我上一篇文章:全文搜索-ElasticSearch 有朋友私信我上一篇没有环境 ...