Socket发送文件

1.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
    {
        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 == 0)
            {
                throw new ArgumentException("参数buffer 为null ,或者长度为 0");
            }

            int flag = 0;
            try
            {
                int totalLen = buffer.Length;
                int sndLen = 0;

                while (true)
                {
                    if ((socket.Poll(outTime * 100, SelectMode.SelectWrite) == true))
                    {        // 收集了足够多的传出数据后开始发送
                        sndLen = socket.Send(buffer, sndLen, totalLen, SocketFlags.None);
                        totalLen -= sndLen;
                        if (totalLen == 0)
                        {                                        // 数据已经全部发送
                            flag = 0;
                            break;
                        }
                        else
                        {
                            if (sndLen > 0)
                            {                                    // 数据部分已经被发送continue;
                            }
                            else
                            {                                                // 发送数据发生错误
                                flag = -2;
                                break;
                            }
                        }
                    }
                    else
                    {                                                        // 超时退出
                        flag = -1;
                        break;
                    }
                }
            }
            catch (SocketException e)
            {

                flag = -3;
            }
            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("127.0.0.1");
            IPEndPoint endpoint = new IPEndPoint(address, 11000);
            //创建服务端负责监听的套接字,参数(使用IPV4协议,使用流式连接,使用TCO协议传输数据)
            Thread.Sleep(1500);
            Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            socket.Connect(endpoint);
            if (socket.Connected)
            {
                Console.WriteLine(socket.RemoteEndPoint + "连接成功");
            }
            if (fileName == null || maxBufferLength <= 0)
            {
                throw new ArgumentException("待发送的文件名称为空或发送缓冲区的大小设置不正确.");
            }
            int flag = 0;
            try
            {
                FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read);
                long fileLen = fs.Length;                        // 文件长度
                long leftLen = fileLen;                            // 未读取部分
                int readLen = 0;                                // 已读取部分
                byte[] buffer = null;

                if (fileLen <= maxBufferLength)
                {            /* 文件可以一次读取*/
                    buffer = new byte[fileLen];
                    readLen = fs.Read(buffer, 0, (int)fileLen);
                    flag = SendData(socket, buffer, outTime);
                }
                else
                {
                    /* 循环读取文件,并发送 */
                    while (leftLen != 0)
                    {
                        if (leftLen < maxBufferLength)
                        {
                            buffer = new byte[leftLen];
                            readLen = fs.Read(buffer, 0, Convert.ToInt32(leftLen));
                        }
                        else
                        {
                            buffer = new byte[maxBufferLength];
                            readLen = fs.Read(buffer, 0, maxBufferLength);
                        }
                        if ((flag = SendData(socket, buffer, outTime)) < 0)
                        {
                            break;
                        }
                        leftLen -= readLen;
                    }
                }
                fs.Flush();
                fs.Close();
            }
            catch (IOException e)
            {

                flag = -4;
            }
            if (flag == 0)
            {
                Console.WriteLine(fileName + "文件发送成功");
                socket.Close();
                Console.WriteLine("连接关闭");
            }
            else
            {
                Console.WriteLine(fileName + "文件发送失败,i=" + flag);
            }
            return flag;
        }
        private static void WatchConnecting()
        {
            while (true)//持续不断的监听客户端的请求
            {
                //开始监听 客户端连接请求,注意:Accept方法,会阻断当前的线程
                Socket connection = socketWatch.Accept();
                if (connection.Connected)
                {

                    //创建通信线程
                    Thread thradRecMsg = new Thread(RecMsg);
                    thradRecMsg.IsBackground = true;
                    thradRecMsg.Start(connection);

                }
            }

        }
        ////// 接收消息
        private static void RecMsg(object socketClientPara)
        {
            string fileName = $@"d:HQ.dat";//获得用户保存文件的路径
            Socket socketClient = socketClientPara as Socket;
            FileStream fs = null;
            while (true)
            {
                //定义一个接受用的缓存区(100M字节数组)
                //将接收到的数据存入arrMsgRec数组,并返回真正接受到的数据的长度
                if (socketClient.Connected)
                {
                    try
                    {
                        //因为终端每次发送文件的最大缓冲区是512字节,所以每次接收也是定义为512字节
                        byte[] buffer = new byte[512];
                        int size = 0;
                        //统计实际文件大小
                        long len = 0;

                        //创建文件流,然后让文件流来根据路径创建一个文件
                        fs = new FileStream(fileName, FileMode.Append);
                        //从终端不停的接受数据,然后写入文件里面,只到接受到的数据为0为止,则中断连接
                        DateTime oTimeBegin = DateTime.Now;

                        while ((size = socketClient.Receive(buffer, 0, buffer.Length, SocketFlags.None)) > 0)
                        {
                            fs.Write(buffer, 0, size);
                            len += size;
                        }
                        DateTime oTimeEnd = DateTime.Now;
                        TimeSpan oTime = oTimeEnd.Subtract(oTimeBegin);
                        fs.Flush();
                        fs.Close();
                        socketClient.Close();
                        Console.WriteLine("文件保存成功:" + fileName);
                        Console.WriteLine("接收文件用时:" + oTime.ToString() + ",文件大小:" + len / 1024 + "kb");
                    }
                    catch (Exception ex)
                    {
                        if (fs != null)
                        {
                            fs.Dispose();
                        }
                        if (File.Exists(fileName))
                        {
                            File.Delete(fileName);
                        }
                        Console.WriteLine(socketClient.RemoteEndPoint + "下线了");

                        break;
                    }
                }
                else
                {

                }
            }
        }
        private static Thread threadWatch = null;
        private static Socket socketWatch = null;
        public static void AcceptFile(string ip, int port, string fileName)
        { //创建服务端负责监听的套接字,参数(使用IPV4协议,使用流式连接,使用Tcp协议传输数据)
            socketWatch = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            //获取Ip地址对象
            IPAddress address = IPAddress.Parse("127.0.0.1");
            //创建包含Ip和port的网络节点对象
            IPEndPoint endpoint = new IPEndPoint(address, 11000);
            //将负责监听的套接字绑定到唯一的Ip和端口上
            socketWatch.Bind(endpoint);
            //设置监听队列的长度
            socketWatch.Listen(10);
            connectDone.Set();
            //创建负责监听的线程,并传入监听方法
            threadWatch = new Thread(WatchConnecting);
            threadWatch.IsBackground = true;//设置为后台线程
            threadWatch.Start();//开始线程

        }
        public static void CloseTcpSocket()
        {

            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, 512, 10000);
            Console.WriteLine("文件从"+fromPath+"到"+toPath+"移动成功!!!!");
        }

    }
}

2. 发送代码
   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);
        }
       
时间: 2024-11-06 18:16:47

Socket发送文件的相关文章

java socket 发送文件

客户端: package tt; import java.io.DataOutputStream; import java.io.File; import java.io.FileInputStream; import java.net.InetSocketAddress; import java.net.Socket; public class ClientTcpSend { public static void main(String[] args) { int length = 0; by

android开发,socket发送文件,read阻塞,得不到文件尾-1

这是我的接收文件代码:开始可以读取到-1,但是现在又读取不到了,所以才加上红色字解决的(注释的代码) File file = new File(mfilePath,"chetou."+entity.mediaType); if(!file.exists()) file.createNewFile(); FileOutputStream fos =new FileOutputStream(file); //将接收的文件保存到对应的路径 byte[] sendBytes =new byte

Python--网络编程-----通过socket收发文件软件开发--面向对象开发

服务端实现 1 import socket 2 import struct 3 import json 4 import os 5 6 7 class MYTCPServer: 8 address_family = socket.AF_INET 9 socket_type = socket.SOCK_STREAM 10 allow_reuse_address = False 11 max_packet_size = 8192 12 coding = 'utf-8' 13 request_queu

winform学习日志(二十三)---------------socket(TCP)发送文件

一:由于在上一个随笔的基础之上拓展的所以直接上代码,客户端: using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using System.Net.Sockets; using Sys

3Python全栈之路系列之基于socket实现文件上传

Python全栈之路系列之基于socket实现文件上传 发布时间:2017年3月16日 00:04 浏览(106) 评论(0) 分类:Python 前言 此处没有前言 粘包 在实现发送文件功能之前我们先来理解下粘包的问题,下面有两张图,我觉得很清晰的就可以理解到了. 正常情况下发送文件 第一步: 客户端把获取到的文件总大小(size=65426)先放到缓冲区,然后发送给服务端 第二步: 此时客户端接收到的文件总大小就是65426 粘包的问题下发送文件 第一步: 客户端把获取到的文件总大小(siz

socket头文件

一 三种类型的套接字:1.流式套接字(SOCKET_STREAM)    提供面向连接的可靠的数据传输服务.数据被看作是字节流,无长度限制.例如FTP协议就采用这种.2.数据报式套接字(SOCKET_DGRAM)    提供无连接的数据传输服务,不保证可靠性.3.原始式套接字(SOCKET_RAW)    该接口允许对较低层次协议,如IP,ICMP直接访问. 二 基本套接字系统调有有如下一些:    创建套接字: socket()    绑定本机端口: bind()    建立连接: conne

java实现客户端向服务器发送文件的操作

服务器源代码: import java.io.BufferedReader; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.net.ServerSocket;

Socket大文件上传

1 public sealed class SocketData 2 { 3 private SocketData() 4 { 5 } 6 7 public static SendFileMode SendFile(Socket socket, string fileName, int maxBufferLength) 8 { 9 SendFileMode flag = SendFileMode.Success; 10 try 11 { 12 using (Stream fs = new Fil

Android Socket 发送广播包的那些坑

Socket广播包经常被用于局域网内的两台设备之间互相发现和消息传递,在Android应用开发过程中,也经常会遇到这样的需求,例如:两台Android设备之间.Android与手环等智能硬件之间.Android与Windows电脑之间等等. 本文主要介绍在Android中使用Socket开发广播包程序时需要注意的编程事项,以及解决方法. 首先给出一段Android发送广播包的示例代码: DatagramSocket socket = new DatagramSocket(8000); socke