Socket发送文件
.Net.cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks; namespace SocketIM
{
////// Net : 提供静态方法,对常用的网络操作进行封装
public class Net
{
public class ObjectState
{
public string fileName { get; set; }
public Socket workSocket { get; set; }
public Thread workThread { get; set; }
}
private Net()
{
} ////// 向远程主机发送数据
//////要发送数据且已经连接到远程主机的 Socket///待发送的数据///发送数据的超时时间,以秒为单位,可以精确到微秒///0:发送数据成功;-1:超时;-2:发送数据出现错误;-3:发送数据时出现异常////// 当 outTime 指定为-1时,将一直等待直到有数据需要发送
public static int SendData(Socket socket, byte[] buffer, int outTime)
{
if (socket == null || socket.Connected == false)
{
throw new ArgumentException("参数socket 为null,或者未连接到远程计算机");
}
if (buffer == null || buffer.Length == )
{
throw new ArgumentException("参数buffer 为null ,或者长度为 0");
} int flag = ;
try
{
int totalLen = buffer.Length;
int sndLen = ; while (true)
{
if ((socket.Poll(outTime * , SelectMode.SelectWrite) == true))
{ // 收集了足够多的传出数据后开始发送
sndLen = socket.Send(buffer, sndLen, totalLen, SocketFlags.None);
totalLen -= sndLen;
if (totalLen == )
{ // 数据已经全部发送
flag = ;
break;
}
else
{
if (sndLen > )
{ // 数据部分已经被发送continue;
}
else
{ // 发送数据发生错误
flag = -;
break;
}
}
}
else
{ // 超时退出
flag = -;
break;
}
}
}
catch (SocketException e)
{ flag = -;
}
return flag;
} ////// 向远程主机发送文件
//////要发送数据且已经连接到远程主机的 socket///待发送的文件名称///文件发送时的缓冲区大小///发送缓冲区中的数据的超时时间///0:发送文件成功;-1:超时;-2:发送文件出现错误;-3:发送文件出现异常;-4:读取待发送文件发生错误////// 当 outTime 指定为-1时,将一直等待直到有数据需要发送
public static int SendFile(string ip, int port, string fileName, int maxBufferLength, int outTime)
{
IPAddress address = IPAddress.Parse(ip);
IPEndPoint endpoint = new IPEndPoint(address, port);
//创建服务端负责监听的套接字,参数(使用IPV4协议,使用流式连接,使用TCO协议传输数据)
Thread.Sleep();
Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
socket.Connect(endpoint);
if (socket.Connected)
{
Console.WriteLine(socket.RemoteEndPoint + "连接成功");
}
if (fileName == null || maxBufferLength <= )
{
throw new ArgumentException("待发送的文件名称为空或发送缓冲区的大小设置不正确.");
}
int flag = ;
try
{
FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read);
long fileLen = fs.Length; // 文件长度
long totalLen = fileLen; // 未读取部分
int readLen = ; // 已读取部分
byte[] buffer = null; if (fileLen <= maxBufferLength)
{ /* 文件可以一次读取*/
buffer = new byte[fileLen];
readLen = fs.Read(buffer, , (int)fileLen);
flag = SendData(socket, buffer, outTime);
}
else
{
/* 循环读取文件,并发送 */
while (totalLen != )
{
if (totalLen < maxBufferLength)
{
buffer = new byte[totalLen];
readLen = fs.Read(buffer, , Convert.ToInt32(totalLen));
}
else
{
buffer = new byte[maxBufferLength];
readLen = fs.Read(buffer, , maxBufferLength);
}
if ((flag = SendData(socket, buffer, outTime)) < )
{
break;
}
totalLen -= readLen;
}
}
fs.Flush();
fs.Close();
socket.Shutdown(SocketShutdown.Both);
socket.Close();
}
catch (IOException e)
{ flag = -;
}
if (flag == )
{
Console.WriteLine(fileName + "文件发送成功");
socket.Close();
Console.WriteLine("连接关闭");
}
else
{
Console.WriteLine(fileName + "文件发送失败,i=" + flag);
}
return flag;
}
private static void WatchConnecting(object info)
{
ObjectState state = (ObjectState)info;
Socket socketWatch = state.workSocket;
while (true)//持续不断的监听客户端的请求
{
//开始监听 客户端连接请求,注意:Accept方法,会阻断当前的线程
Socket connection = socketWatch.Accept(); if (connection.Connected)
{ //创建通信线程
Thread thradRecMsg = new Thread(RecMsg);
state.workSocket = connection;
state.workThread = thradRecMsg;
thradRecMsg.IsBackground = true;
thradRecMsg.Start(state); }
} }
////// 接收消息
private static void RecMsg(object socketClientPara)
{ ObjectState state = (ObjectState)socketClientPara;
string fileName = state.fileName;//$@"d:HQ.dat";//获得用户保存文件的路径
Socket socketClient = state.workSocket;
FileStream fs = null;
while (true)
{
//定义一个接受用的缓存区(100M字节数组)
//将接收到的数据存入arrMsgRec数组,并返回真正接受到的数据的长度
if (socketClient.Connected)
{
try
{
//因为终端每次发送文件的最大缓冲区是512字节,所以每次接收也是定义为512字节
byte[] buffer = new byte[];
int size = ;
//统计实际文件大小
long len = ;
//创建文件流,然后让文件流来根据路径创建一个文件
fs = new FileStream(fileName, FileMode.Append);
DateTime oTimeBegin = DateTime.Now;
//从终端不停的接受数据,然后写入文件里面,只到接受到的数据为0为止,则中断连接
while ((size = socketClient.Receive(buffer, , buffer.Length, SocketFlags.None)) > )
{
fs.Write(buffer, , size);
len += size;
}
DateTime oTimeEnd = DateTime.Now;
TimeSpan oTime = oTimeEnd.Subtract(oTimeBegin);
fs.Flush();
fs.Close(); socketClient.Shutdown(SocketShutdown.Both);
socketClient.Close();
Console.WriteLine("文件保存成功:" + fileName);
Console.WriteLine("接收文件用时:" + oTime.ToString() + ",文件大小:" + len / + "kb");
}
catch (Exception ex)
{
if (fs != null)
{
fs.Dispose();
}
if (File.Exists(fileName))
{
File.Delete(fileName);
}
Console.WriteLine(socketClient.RemoteEndPoint + "下线了"); break;
}
}
else
{ }
}
} public static void AcceptFile(string ip, int port, string fileName)
{
//创建服务端负责监听的套接字,参数(使用IPV4协议,使用流式连接,使用Tcp协议传输数据)
Socket socketListen = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
socketListen.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
//获取Ip地址对象
IPAddress address = IPAddress.Parse(ip);
//创建包含Ip和port的网络节点对象
IPEndPoint endpoint = new IPEndPoint(address, port); //将负责监听的套接字绑定到唯一的Ip和端口上
socketListen.Bind(endpoint);
//设置监听队列的长度
socketListen.Listen();
connectDone.Set();
ObjectState state = new ObjectState(); //创建负责监听的线程,并传入监听方法
Thread threadWatch = new Thread(WatchConnecting);
state.fileName = fileName;
state.workSocket = socketListen;
state.workThread = threadWatch;
threadWatch.IsBackground = true;//设置为后台线程
threadWatch.Start(state);//开始线程 }
public static void CloseTcpSocket(Thread threadWatch, Socket socketWatch)
{ threadWatch.Abort();
socketWatch.Close();
Console.WriteLine("服务器关闭监听");
}
public static ManualResetEvent connectDone = new ManualResetEvent(false);
public static void FileMove(string ip, int port, string fromPath, string toPath)
{ AcceptFile(ip, port, toPath);
connectDone.WaitOne();
int i = SendFile(ip, port, fromPath, , );
Console.WriteLine("文件从" + fromPath + "到" + toPath + "移动成功!!!!");
} }
}
.调用代码
private void button1_Click(object sender, EventArgs e)
{
//string topath = $@"d:HQ.dat";
//string frompath = $@"e:\HQ.dat";
//Net.FileMove("127.0.0.1", 11000, frompath,topath);
string topath = $@"d:bb\HQ.dat";
string frompath = $@"d:aa\HQ.dat";
Net.FileMove("127.0.0.1", , frompath, topath);
}
Socket发送文件的更多相关文章
- android开发,socket发送文件,read阻塞,得不到文件尾-1
这是我的接收文件代码:开始可以读取到-1,但是现在又读取不到了,所以才加上红色字解决的(注释的代码) File file = new File(mfilePath,"chetou." ...
- Python -- 网络编程 -- Socket发送文件
客户端如果直接send两次,一次发文件名,一次发文件内容 服务端接受的时候会一起接收,不知怎么分开发送,或者分开接收, 或者全部接收再解析内容 今天发现传送mp3文件的时候没问题,传送文本文件的话,以 ...
- python 通过 socket 发送文件
目录结构: client: #!/usr/bin/env python # -*-coding:utf-8 -*- import socket, struct, json download_dir = ...
- java socket 发送文件
客户端: package tt; import java.io.DataOutputStream; import java.io.File; import java.io.FileInputStrea ...
- socket(TCP)发送文件
一:由于在上一个随笔的基础之上拓展的所以直接上代码,客户端: using System; using System.Collections.Generic; using System.Componen ...
- C# socket 发送图片和文件
先说服务端:界面:如图: 界面设计源码 namespace SocketJPGToTxt { partial class Form1 { /// <summary> /// 必需的设计器变 ...
- socket发送文字、图片、文件---基于python实现
socket官方文档:https://docs.python.org/2/library/socket.html socket中文详细介绍:http://blog.csdn.net/rebelqsp/ ...
- C#使用FileSystemWatcher来监控指定文件夹,并使用TCP/IP协议通过Socket发送到另外指定文件夹
项目需求: 局域网内有两台电脑,电脑A(Windows系统)主要是负责接收一些文件(远程桌面粘贴.FTP上传.文件夹共享等方式),希望能在A接收文件后自动传输到电脑B(Windows系统)来做一个备份 ...
- 利用Socket远程发送文件
思想: 1.注意使用两个通道,一个普通对象通信通道,另一个纯净的文件字节流通道 2.利用通信通道发送文件请求,新建字节流通道,开始发送文件
随机推荐
- 《DSP using MATLAB》Problem 2.18
1.代码: function [y, H] = conv_tp(h, x) % Linear Convolution using Toeplitz Matrix % ----------------- ...
- 自定义redis session
1.思路 2.程序实现 1.用户系统类 这里模拟一个蹩脚的用户系统类(userSystem),如下: #coding=utf-8 #Redis实现用户系统 __author__ = 'beginman ...
- flash exe to flv swf
一般婚纱视频的文件都是用adobe软件转化为exe文件,所以只能用adobe flash打开,想上传到网上供朋友欣赏,却发现格式不对,那么我们可以用以下的方法将exe格式的视频转化为swf和flv等视 ...
- RabbitMQ内存爆出问题解决思路
http://www.bubuko.com/infodetail-2121050.html RabbitMQ升级到3.6.1版本后,随着业务和系统功能的增加,出现RabbitMQ内存陡增直至服务宕掉的 ...
- Eclipse实用用快捷键
1.ctrl+shift+o 添加必须import并删除无用import.代码被改动时容易产生很多无用引用,此时这个快捷键就可以一次把如下的引用删掉了
- Devexpres下窗体带阴影的边框效果
public partial class Form1 : DevExpress.XtraEditors.XtraForm { public Form1() { InitializeComponent( ...
- GREENPLUM简介
什么是GREENPLUM? 对于很多IT人来说GREENPLUM是个陌生的名字.简单的说它就是一个与ORACLE, DB2一样面向对象的关系型数据库.我们通过标准的SQL可以对GP中的数据进行访问存取 ...
- HDU 4586 Play the Dice(数学期望)
Play the Dice Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others)Tot ...
- window.onload()和$(document).ready()区别
执行时间:window.onload:必须等待网页中所有的内容加载完毕后(包括图片)才能执行;$(document).ready();网页中所有DOM结构绘制完毕后就执行,可能DOM元素关联的东西并没 ...
- Windows 上用IntelliJ Idea调试百度大数据分析框架Apache Doris FE
A. 环境准备 1. 安装jdk1.8+, Intelij IDEA 2. linux上编译好fe前端代码,主要目的是获取自动生成的代码,加入到前段工程里面去用于在idea中编译fe工程.具体编译请参 ...