C# Socket 檔案傳送傳輸

取名太纠结發表於2024-04-26

客戶端向伺服器傳送檔案:

伺服器:

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 Server
{
class Program
{
static void Main(string[] args)
{
IPEndPoint ip = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 8080);
Socket sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
sock.Bind(ip);
sock.Listen(1);

        while(true)
        {
            Socket client = sock.Accept();

            if (client.Connected)
            {
                Thread clientThread = new Thread(new ParameterizedThreadStart(MyClient));
                clientThread.IsBackground = true;
                clientThread.Start(client);
            }
        }
    }

    private const int BUFFERSIZE = 1024/* * 1024*/;
    private static string _path = @"D:\";

    private static void MyClient(object socket)
    {
        Socket clientSocket = socket as Socket;
        string clientName = clientSocket.RemoteEndPoint.ToString();
        Console.WriteLine("新客戶端連線:" + clientName);

        try
        {
            while(true)
            {
                byte[] buffer = new byte[BUFFERSIZE];
                int countReceive = clientSocket.Receive(buffer);
                string receiveStr = Encoding.Default.GetString(buffer, 0, countReceive);
                Console.WriteLine("收到:" + clientName + ":" + receiveStr);
                string[] command = receiveStr.Split(',');

                string fileName = null;
                long fileLength = -1L;

                if (command[0] == "nameAndLength")
                {
                    fileName = command[1];
                    fileLength = long.Parse(command[2]);
                    clientSocket.Send(Encoding.Default.GetBytes("ok"));
                    Console.WriteLine("接收檔案:" + fileName + " 請等候……");

                    long recieved = 0L;

                    using (FileStream fsWriter = new FileStream(Path.Combine(_path,fileName), FileMode.Create, FileAccess.Write, FileShare.None))
                    {
                        int recive;

                        while(recieved < fileLength)
                        {
                            recive = clientSocket.Receive(buffer);
                            fsWriter.Write(buffer, 0, recive);
                            fsWriter.Flush();
                            recieved += recive;
                            Console.WriteLine("已接收資料:{0}/{1}", recieved.ToString(), fileLength.ToString());
                        }

                        Console.WriteLine("接收完成……\n");
                    }
                }
            }
        }
        catch (Exception)
        {
            Console.WriteLine("客戶端:" + clientName + "退出");
        }
    }
}

}
客戶端:

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.Tasks;

namespace Client
{
class Program
{
private static Socket _sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

    static void Main(string[] args)
    {
        _sock.Connect(new IPEndPoint(IPAddress.Parse("127.0.0.1"), 8080));
        Console.WriteLine("連線成功…");

        while (true)
        {
            Console.WriteLine("請輸入需要傳送的檔案路徑:");
            string path = Console.ReadLine();

            try
            {
                using (FileStream fsReader = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.None))
                {
                    long sended = 0L;
                    long fileLength = fsReader.Length;
                    string fileName = Path.GetFileName(path);
                    string sendStr = "nameAndLength," + fileName + "," + fileLength.ToString();

                    _sock.Send(Encoding.Default.GetBytes(sendStr));

                    const int BUFFERSIZE = 1024/* * 1024*/;
                    byte[] buffer = new byte[32];

                    int recvCount = _sock.Receive(buffer);
                    string mes = Encoding.Default.GetString(buffer, 0, recvCount);

                    if (mes == "ok")
                    {
                        Console.WriteLine("傳送檔案:" + fileName + " 請等待……");
                        byte[] fileBuffer = new byte[BUFFERSIZE];

                        int readCount;
                        int sending;
                        int readCountLeft;

                        while ((readCount = fsReader.Read(fileBuffer, 0, BUFFERSIZE)) != 0)
                        {
                            sending = 0;
                            readCountLeft = readCount;
                            while ((sending += _sock.Send(fileBuffer, sending, readCountLeft, SocketFlags.None)) < readCount) // 判斷髮送完
                            {
                                readCountLeft = readCount - sending;
                            }
                            sended += sending;
                            Console.WriteLine("傳送資料:{0}/{1}", sended.ToString(), fileLength.ToString());
                        }

                        Console.WriteLine("傳送完畢……\n");
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }
    }
}

}

命令列
客戶端向伺服器發檔案。

伺服器:

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 Server
{
class Program
{
/exe 127.0.0.1 8080 D:\/
static void Main(string[] args)
{
int port = int.Parse(args[1]);
_path = args[2];
Console.WriteLine("開啟伺服器:{0}", args[0] + " " + args[1]);
IPEndPoint ip = new IPEndPoint(IPAddress.Parse(args[0]), port);
Socket sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
sock.Bind(ip);
sock.Listen(100);

        while (true)
        {
            Socket client = sock.Accept();

            if (client.Connected)
            {
                Thread clientThread = new Thread(new ParameterizedThreadStart(MyClient));
                clientThread.IsBackground = true;
                clientThread.Start(client);
            }
        }
    }

    private const int BUFFERSIZE = 1024 * 1024;
    private static string _path = @"D:\";

    private static void MyClient(object socket)
    {
        Socket clientSocket = socket as Socket;
        string clientName = clientSocket.RemoteEndPoint.ToString();
        Console.WriteLine("新客戶端連線:" + clientName);

        try
        {
            while (true)
            {
                byte[] buffer = new byte[BUFFERSIZE];
                int countReceive = clientSocket.Receive(buffer);
                string receiveStr = Encoding.Default.GetString(buffer, 0, countReceive);
                Console.WriteLine("收到:" + clientName + ":" + receiveStr);
                string[] command = receiveStr.Split(',');

                string fileName = null;
                long fileLength = -1L;

                if (command[0] == "nameAndLength")
                {
                    fileName = command[1];
                    fileLength = long.Parse(command[2]);
                    clientSocket.Send(Encoding.Default.GetBytes("ok"));
                    Console.WriteLine("接收檔案:" + fileName + " 請等候……");

                    long recieved = 0L;

                    using (FileStream fsWriter = new FileStream(Path.Combine(_path, fileName), FileMode.Create, FileAccess.Write, FileShare.None))
                    {
                        int recive;

                        while (recieved < fileLength)
                        {
                            recive = clientSocket.Receive(buffer);
                            fsWriter.Write(buffer, 0, recive);
                            fsWriter.Flush();
                            recieved += recive;
                            Console.WriteLine("已接收資料:{0}/{1}", recieved.ToString(), fileLength.ToString());
                        }

                        Console.WriteLine("接收完成……\n");
                    }
                }
            }
        }
        catch (Exception)
        {
            Console.WriteLine("客戶端:" + clientName + "退出");
        }
    }
}

}
客戶端:

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.Tasks;

namespace Client
{
class Program
{
private static Socket _sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

    /*exe 127.0.0.1 8080 D:\\*/
    static void Main(string[] args)
    {
        int port = int.Parse(args[1]);
        string path = args[2];
        _sock.Connect(new IPEndPoint(IPAddress.Parse(args[0]), port));
        Console.WriteLine("連線成功…");
        bool firstFlag = true;

        while (true)
        {
            if (!firstFlag)
            {
                Console.WriteLine("請輸入需要傳送的檔案路徑:");
                path = Console.ReadLine();
            }

            try
            {
                using (FileStream fsReader = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.None))
                {
                    long sended = 0L;
                    long fileLength = fsReader.Length;
                    string fileName = Path.GetFileName(path);
                    string sendStr = "nameAndLength," + fileName + "," + fileLength.ToString();

                    _sock.Send(Encoding.Default.GetBytes(sendStr));

                    const int BUFFERSIZE = 1024 * 1024;
                    byte[] buffer = new byte[32];

                    int recvCount = _sock.Receive(buffer);
                    string mes = Encoding.Default.GetString(buffer, 0, recvCount);

                    if (mes == "ok")
                    {
                        Console.WriteLine("傳送檔案:" + fileName + " 請等待……");
                        byte[] fileBuffer = new byte[BUFFERSIZE];

                        int readCount;
                        int sending;
                        int readCountLeft;

                        while ((readCount = fsReader.Read(fileBuffer, 0, BUFFERSIZE)) != 0)
                        {
                            sending = 0;
                            readCountLeft = readCount;
                            while ((sending += _sock.Send(fileBuffer, sending, readCountLeft, SocketFlags.None)) < readCount) // 判斷髮送完
                            {
                                readCountLeft = readCount - sending;
                            }
                            sended += sending;
                            Console.WriteLine("傳送資料:{0}/{1}", sended.ToString(), fileLength.ToString());
                        }

                        Console.WriteLine("傳送完畢……\n");
                        firstFlag = false;
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }
    }
}

}

相關文章