最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C# Socket文件上傳至服務(wù)器的操作方法

 更新時間:2024年05月24日 11:31:12   作者:不自由的小碼  
文件上傳有FTP、WebApi、WebService等等,這次我們來實現(xiàn)一個基于socket通信的本地客戶端上傳文件到服務(wù)器的例子,這篇文章主要介紹了C# Socket文件上傳至服務(wù)器的操作方法,需要的朋友可以參考下

前言

文件上傳有FTP、WebApi、WebService等等,這次我們來實現(xiàn)一個基于socket通信的本地客戶端上傳文件到服務(wù)器的例子。

運行效果

一、Socket(套接字)概念

說起socket通信,那就不得不介紹一下套接字(socket),套接字是通信的基石,是支持TCP/IP協(xié)議的網(wǎng)絡(luò)通信的基本操作單元,套接字Socket=(IP地址:端口號)。就是對網(wǎng)絡(luò)中不同主機上的應(yīng)用進程之間進行雙向通信的端點的抽象。一個套接字就是網(wǎng)絡(luò)上進程通信的一端,提供了應(yīng)用層進程利用網(wǎng)絡(luò)協(xié)議交換數(shù)據(jù)的機制。從所處的地位來講,套接字上聯(lián)應(yīng)用進程,下聯(lián)網(wǎng)絡(luò)協(xié)議棧,是應(yīng)用程序通過網(wǎng)絡(luò)協(xié)議進行通信的接口,是應(yīng)用程序與網(wǎng)絡(luò)協(xié)議棧進行交互的接口,它包含進行網(wǎng)絡(luò)通信必須的五種信息:連接使用的協(xié)議,本地主機的IP地址,本地進程的協(xié)議端口,遠地主機的IP地址,遠地進程的協(xié)議端口。

二、Socket通信的建立

建立Socket連接至少需要一對套接字,其中一個運行于客戶端,稱為ClientSocket ,另一個運行于服務(wù)器端,稱為ServerSocket 。

三、通信流程

根據(jù)連接啟動的方式以及本地套接字要連接的目標,套接字之間的連接過程可以分為三個步驟:
(1)服務(wù)器監(jiān)聽。
(2)客戶端請求。
(3)連接確認。
1.服務(wù)器監(jiān)聽
所謂服務(wù)器監(jiān)聽,是指服務(wù)器端套接字并不定位具體的客戶端套接字,而是處于等待連接的狀態(tài),實時監(jiān)控網(wǎng)絡(luò)狀態(tài)。
2.客戶端請求
所謂客戶端請求,是指由客戶端的套接字提出連接請求,要連接的目標是服務(wù)器端的套接字。為此,客戶端的套接字必須首先描述它要連接的服務(wù)器的套接字,指出服務(wù)器端套接字的地址和端口號,然后就向服務(wù)器端接字提出連接請求 。
3.連接確認
所謂連接確認,是指當服務(wù)器端套接字監(jiān)聽到或者說接收到客戶端套接字的連接請求,就會響應(yīng)客戶端套接字的請求,建立一個新的線程,并把服務(wù)器端套接字的描述發(fā)送給客戶端。一旦客戶端確認了此描述,連接就建立好了。而服務(wù)器端套接字繼續(xù)處于監(jiān)聽狀態(tài),接收其他客戶端套接字的連接請求。

四、實現(xiàn)

1.ClientSocket

在這里插入圖片描述

本機IP地址在窗體加載的時候賦值。

     private void FrmMain_Load(object sender, EventArgs e)
     {
       //獲得本機的IP地址   
       this.textBox4.Text = Dns.GetHostByName(Dns.GetHostName()).AddressList[0].ToString();
      }

接下來我們正式開始,點擊瀏覽,選擇需要上傳的文件。此時我們獲取當前文件的全路徑、文件名稱及合計字節(jié)。

        /// <summary>
        /// 瀏覽
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button1_Click(object sender, EventArgs e)
        {
            //選擇要進行傳輸?shù)奈募?  
            if (this.openFileDialog1.ShowDialog() == DialogResult.OK)
            {
                FileInfo EzoneFile = new FileInfo(this.openFileDialog1.FileName);
                this.textBox1.Text = EzoneFile.FullName;
                this.textBox2.Text = EzoneFile.Name;
                this.textBox3.Text = EzoneFile.Length.ToString();
            }
        }

點擊發(fā)送按鈕,將文件以字節(jié)流的形式發(fā)送到服務(wù)器端,此時應(yīng)該單獨開一個子線程以保證監(jiān)聽運行,監(jiān)聽事件定義StartSend。

        /// <summary>
        /// 開始發(fā)送
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button2_Click(object sender, EventArgs e)
        {
            //開啟文件傳輸子線程   
            Thread TempThread = new Thread(new ThreadStart(this.StartSend));
            TempThread.Start();
        }

StartSend事件中,根據(jù)文件路徑創(chuàng)建一個文件對象,配置操作流、創(chuàng)建連接對象、IP\Port等等關(guān)鍵信息。首先我們來創(chuàng)建一個幫助類FileClientSocket.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Sockets;
using System.Text;
namespace TouchSocketClient
{
    public class FileClientSocket
    {
        public static int SendData(Socket s, byte[] data)
        {
            int total = 0;
            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 = 0;
            int dataleft = size;
            byte[] data = new byte[size];
            int recv;
            while (total < size)
            {
                recv = s.Receive(data, total, dataleft, SocketFlags.None);
                if (recv == 0)
                {
                    data = null;
                    break;
                }
                total += recv;
                dataleft -= recv;
            }
            return data;
        }
        public static int SendVarData(Socket s, byte[] data)
        {
            int total = 0;
            int size = data.Length;
            int dataleft = size;
            int sent;
            byte[] datasize = new byte[4];
            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;
        }
        public static byte[] ReceiveVarData(Socket s)
        {
            int total = 0;
            int recv;
            byte[] datasize = new byte[4];
            recv = s.Receive(datasize, 0, 4, SocketFlags.None);
            int size = BitConverter.ToInt32(datasize, 0);
            int dataleft = size;
            byte[] data = new byte[size];
            while (total < size)
            {
                recv = s.Receive(data, total, dataleft, SocketFlags.None);
                if (recv == 0)
                {
                    data = null;
                    break;
                }
                total += recv;
                dataleft -= recv;
            }
            return data;
        }
    }
}

StartSend方法實現(xiàn)

        private void StartSend()
        {
            //創(chuàng)建一個文件對象   
            FileInfo EzoneFile = new FileInfo(this.textBox1.Text);
            //打開文件流   
            FileStream EzoneStream = EzoneFile.OpenRead();
            //包的大小   
            int PacketSize = int.Parse(this.textBox6.Text);
            //包的數(shù)量   
            int PacketCount = (int)(EzoneStream.Length / ((long)PacketSize));
            //最后一個包的大小   
            int LastDataPacket = (int)(EzoneStream.Length - ((long)(PacketSize * PacketCount)));
            //指向遠程服務(wù)端節(jié)點   
            IPEndPoint ipep = new IPEndPoint(IPAddress.Parse(txtIP.Text.Trim()), int.Parse(this.textBox5.Text));
            //創(chuàng)建套接字   
            Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            //連接到發(fā)送端   
            client.Connect(ipep);
            //獲得客戶端節(jié)點對象   
            IPEndPoint clientep = (IPEndPoint)client.RemoteEndPoint;
            //獲得客戶端的IP地址   
            //this.textBox7.Text=clientep.Address.ToString();   
            //發(fā)送[文件名]到客戶端   
            FileClientSocket.SendVarData(client,System.Text.Encoding.Unicode.GetBytes(EzoneFile.Name));
            //發(fā)送[包的大小]到客戶端   
            FileClientSocket.SendVarData(client,System.Text.Encoding.Unicode.GetBytes(PacketSize.ToString()));
            //發(fā)送[包的總數(shù)量]到客戶端   
            FileClientSocket.SendVarData(client,System.Text.Encoding.Unicode.GetBytes(PacketCount.ToString()));
            //發(fā)送[最后一個包的大小]到客戶端   
            FileClientSocket.SendVarData(client,System.Text.Encoding.Unicode.GetBytes(LastDataPacket.ToString()));
            //數(shù)據(jù)包   
            byte[] data = new byte[PacketSize];
            //開始循環(huán)發(fā)送數(shù)據(jù)包   
            for (int i = 0; i < PacketCount; i++)
            {
                //從文件流讀取數(shù)據(jù)并填充數(shù)據(jù)包   
                EzoneStream.Read(data, 0, data.Length);
                //發(fā)送數(shù)據(jù)包   
                FileClientSocket.SendVarData(client, data);
            }
            //如果還有多余的數(shù)據(jù)包,則應(yīng)該發(fā)送完畢!   
            if (LastDataPacket != 0)
            {
                data = new byte[LastDataPacket];
                EzoneStream.Read(data, 0, data.Length);
                FileClientSocket.SendVarData(client, data);
            }
            //關(guān)閉套接字   
            client.Close();  
            //關(guān)閉文件流   
            EzoneStream.Close();
            MessageBox.Show("文件傳輸完畢!");
        }

至此客戶端部分已經(jīng)完成,下面開始實現(xiàn)服務(wù)端。

2.ServerSocket

我們新建一個控制臺應(yīng)用程序,TouchSocketServer。

在這里插入圖片描述

在Main方法中 注冊接收事件,并開始子線程進行處理。

static void Main(string[] args)
        {
            //開啟接收線程   
            Thread TempThread = new Thread(new ThreadStart(StartReceive));
            TempThread.Start();
        }

同樣我們服務(wù)端也需要一個Server類(FileSocketServer.cs)

namespace TouchSocketServer
{
    public class FileSocketServer
    {
        public static int SendData(Socket s, byte[] data)
        {
            int total = 0;
            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 = 0;
            int dataleft = size;
            byte[] data = new byte[size];
            int recv;
            while (total < size)
            {
                recv = s.Receive(data, total, dataleft, SocketFlags.None);
                if (recv == 0)
                {
                    data = null;
                    break;
                }
                total += recv;
                dataleft -= recv;
            }
            return data;
        }
        public static int SendVarData(Socket s, byte[] data)
        {
            int total = 0;
            int size = data.Length;
            int dataleft = size;
            int sent;
            byte[] datasize = new byte[4];
            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;
        }
        public static byte[] ReceiveVarData(Socket s)
        {
            int total = 0;
            int recv;
            byte[] datasize = new byte[4];
            recv = s.Receive(datasize, 0, 4, SocketFlags.None);
            int size = BitConverter.ToInt32(datasize, 0);
            int dataleft = size;
            byte[] data = new byte[size];
            while (total < size)
            {
                recv = s.Receive(data, total, dataleft, SocketFlags.None);
                if (recv == 0)
                {
                    data = null;
                    break;
                }
                total += recv;
                dataleft -= recv;
            }
            return data;
        }
    }
}

接收函數(shù)

private static void StartReceive()
        {
            //創(chuàng)建一個網(wǎng)絡(luò)端點
            Console.ForegroundColor = ConsoleColor.DarkRed;
            Console.WriteLine($"{DateTime.Now} [初始化網(wǎng)絡(luò)端點]");
            IPEndPoint ipep = new IPEndPoint(IPAddress.Any, int.Parse("1005"));
            //MessageBox.Show(IPAddress.Any);   
            //創(chuàng)建一個套接字   
            Socket server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            //綁定套接字到端口   
            server.Bind(ipep);
            //開始偵聽(并堵塞該線程)   
            Console.WriteLine($"{DateTime.Now} [開始偵聽并堵塞該線程]");
            server.Listen(10);
            while (true)
            {
                try
                {
                    Socket client = server.Accept();
                    ClientSocket = client;
                    Thread TempThread = new Thread(new ThreadStart(Create));
                    TempThread.Start();
                }
                catch (Exception ex)
                {
                    int k = 0;
                }
            }
        }

創(chuàng)建文件函數(shù)

public static void Create()
        {
            Console.ForegroundColor = ConsoleColor.Green;
            Console.WriteLine($"{DateTime.Now} [創(chuàng)建對象]");
            Socket client = ClientSocket;
            //確認連接   
            //Socket client = server.Accept();
            //獲得客戶端節(jié)點對象   
            Console.ForegroundColor = ConsoleColor.Yellow;
            IPEndPoint clientep = (IPEndPoint)client.RemoteEndPoint;
            Console.WriteLine($"{DateTime.Now} 請求對象:[{clientep.Address}]");
            //獲得[文件名]   
            string SendFileName = System.Text.Encoding.Unicode.GetString(FileSocketServer.ReceiveVarData(client));
            Console.WriteLine($"{DateTime.Now} 文件名稱:[{SendFileName}]");
            //獲得[包的大小]   
            string bagSize = System.Text.Encoding.Unicode.GetString(FileSocketServer.ReceiveVarData(client));
            //獲得[包的總數(shù)量]   
            int bagCount = int.Parse(System.Text.Encoding.Unicode.GetString(FileSocketServer.ReceiveVarData(client)));
            //獲得[最后一個包的大小]   
            string bagLast = System.Text.Encoding.Unicode.GetString(FileSocketServer.ReceiveVarData(client));
            //自動創(chuàng)建文件夾
            string path = $@"{System.AppDomain.CurrentDomain.BaseDirectory}\Log\{clientep.Address}({DateTime.Now.ToString("yyyyMMddhhmmssffffff")})";
            Directory.CreateDirectory(path);
            //創(chuàng)建一個新文件   
            FileStream MyFileStream = new FileStream($@"{path}\" + SendFileName, FileMode.Create, FileAccess.Write);
            Console.WriteLine($"{DateTime.Now} 創(chuàng)建目標:[已創(chuàng)建]");
            //已發(fā)送包的個數(shù)   
            int SendedCount = 0;
            while (true)
            {
                byte[] data = FileSocketServer.ReceiveVarData(client);
                if (data.Length == 0)
                {
                    break;
                }
                else
                {
                    SendedCount++;
                    //將接收到的數(shù)據(jù)包寫入到文件流對象   
                    MyFileStream.Write(data, 0, data.Length);
                    //顯示已發(fā)送包的個數(shù)
                }
            }
            //關(guān)閉文件流   
            MyFileStream.Close();
            //關(guān)閉套接字   
            client.Close();
            Console.WriteLine($"{DateTime.Now} 傳輸結(jié)果:[成功]");
        }

到此這篇關(guān)于C# Socket文件上傳至服務(wù)器的文章就介紹到這了,更多相關(guān)C# Socket文件上傳內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 漢字轉(zhuǎn)拼音軟件制件示例(漢字轉(zhuǎn)字母)

    漢字轉(zhuǎn)拼音軟件制件示例(漢字轉(zhuǎn)字母)

    這篇文章主要介紹了c#漢字轉(zhuǎn)拼音的方法,但不能判斷多音字,大家可以參考修改使用
    2014-01-01
  • c# webapi 配置swagger的方法

    c# webapi 配置swagger的方法

    這篇文章主要介紹了c# webapi 配置swagger的方法,文中示例代碼非常詳細,幫助大家更好的理解和學(xué)習(xí),感興趣的朋友可以了解下
    2020-07-07
  • C#動態(tài)加載程序集的全攻略

    C#動態(tài)加載程序集的全攻略

    在 C# 中,動態(tài)加載程序集是一種常見的需求,特別是在需要模塊化、插件化或運行時擴展功能的場景中,以下是如何實現(xiàn) C# 代碼依賴的動態(tài)加載的詳細說明,結(jié)合了知識庫中的關(guān)鍵信息和實際應(yīng)用技巧,需要的朋友可以參考下
    2025-08-08
  • C#實現(xiàn)獲取系統(tǒng)目錄并以Tree樹叉顯示的方法

    C#實現(xiàn)獲取系統(tǒng)目錄并以Tree樹叉顯示的方法

    這篇文章主要介紹了C#實現(xiàn)獲取系統(tǒng)目錄并以Tree樹叉顯示的方法,可以加深讀者對于C#下數(shù)據(jù)結(jié)構(gòu)實現(xiàn)方法的認識,需要的朋友可以參考下
    2014-07-07
  • C#枚舉類型與位域枚舉Enum

    C#枚舉類型與位域枚舉Enum

    這篇文章介紹了C#中的枚舉類型與位域枚舉Enum,文中通過示例代碼介紹的非常詳細。對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-05-05
  • C#框架winform實現(xiàn)簡單點餐系統(tǒng)

    C#框架winform實現(xiàn)簡單點餐系統(tǒng)

    這篇文章主要為大家詳細介紹了C#框架winform實現(xiàn)簡單點餐系統(tǒng),文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-07-07
  • C#超實用代碼段合集

    C#超實用代碼段合集

    這篇文章主要介紹了C#超實用代碼段合集,涉及C#針對圖標、數(shù)學(xué)運算、拼音、日期、時間及文件夾等的相關(guān)操作技巧,需要的朋友可以參考下
    2015-11-11
  • Unity實現(xiàn)3D射箭小游戲

    Unity實現(xiàn)3D射箭小游戲

    這篇文章主要為大家詳細介紹了Unity實現(xiàn)3D射箭小游戲,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-04-04
  • 使用SkiaSharp在C#中如何生成圖像

    使用SkiaSharp在C#中如何生成圖像

    本文介紹了如何使用SkiaSharp庫在C#中生成和處理圖像,通過創(chuàng)建一個空白圖像并繪制一個正方形,我們展示了如何使用SkiaSharp的基本功能,如創(chuàng)建畫布、繪制圖形和保存圖像
    2025-01-01
  • C#?實例解釋面向?qū)ο缶幊讨械膯我还δ茉瓌t(示例代碼)

    C#?實例解釋面向?qū)ο缶幊讨械膯我还δ茉瓌t(示例代碼)

    本文我介紹了?SOLID?原則中的單一功能原則(single-responsibility?principle),并通過?C#?代碼示例簡明地詮釋了它的含意和實現(xiàn),對C#?面向?qū)ο缶幊淘瓌t感興趣的朋友跟隨小編一起看看吧
    2022-02-02

最新評論

保定市| 来宾市| 安岳县| 任丘市| 晴隆县| 景德镇市| 稷山县| 灵石县| 天峻县| 祥云县| 蓝田县| 贡觉县| 五家渠市| 明溪县| 庐江县| 禄劝| 南华县| 府谷县| 滨州市| 南安市| 鲁甸县| 西充县| 保定市| 揭阳市| 遂川县| 英吉沙县| 铅山县| 托里县| 洛阳市| 沙河市| 沙坪坝区| 永清县| 保康县| 武定县| 甘肃省| 四平市| 霍邱县| 麻城市| 贵港市| 积石山| 固镇县|