成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

基于TCP協(xié)議Socket編程,使用WPF實(shí)現(xiàn)文件上傳和保存文件完整示例

開發(fā) 前端
我們可以使用C#的Socket編程實(shí)現(xiàn)一個(gè)文件上傳系統(tǒng),包括客戶端和服務(wù)端的程序。在程序中使用Socket進(jìn)行網(wǎng)絡(luò)連接和數(shù)據(jù)傳輸,同時(shí)對(duì)連接錯(cuò)誤和文件錯(cuò)誤進(jìn)行適當(dāng)處理和異常捕獲。

需求分析

假設(shè)我們需要實(shí)現(xiàn)一個(gè)基于網(wǎng)絡(luò)的文件上傳系統(tǒng),用戶可以通過客戶端將本地文件上傳到服務(wù)端。這種情況經(jīng)常出現(xiàn)在文件存儲(chǔ)和共享、云存儲(chǔ)等應(yīng)用場景中。使用Socket編程可以實(shí)現(xiàn)高效可靠的文件傳輸。

1、客戶端需求:

  • 用戶可以選擇本地文件進(jìn)行上傳。
  • 用戶需要輸入服務(wù)端的IP地址和端口號(hào)。
  • 客戶端需要將選擇的文件發(fā)送給服務(wù)端進(jìn)行保存。

2、服務(wù)端需求:

  • 服務(wù)端需要監(jiān)聽指定的端口,等待客戶端連接請(qǐng)求。
  • 接收到客戶端連接后,服務(wù)端需要接收文件數(shù)據(jù)。
  • 服務(wù)端需要將接收到的文件保存到指定位置。

3、文件傳輸需求:

  • 傳輸協(xié)議:使用TCP協(xié)議確保可靠的數(shù)據(jù)傳輸。
  • 文件分片:為了減小內(nèi)存開銷和網(wǎng)絡(luò)負(fù)載,將大文件分成多個(gè)較小的數(shù)據(jù)包進(jìn)行傳輸。
  • 文件校驗(yàn):傳輸過程中需要對(duì)文件進(jìn)行校驗(yàn),確保數(shù)據(jù)的完整性。

4、錯(cuò)誤處理需求:

  • 連接錯(cuò)誤:需要處理連接失敗、超時(shí)等錯(cuò)誤情況。
  • 文件錯(cuò)誤:需要處理文件讀取失敗、傳輸中斷等錯(cuò)誤情況。
  • 異常處理:需要處理網(wǎng)絡(luò)異常、IO異常等情況,并提供相應(yīng)的錯(cuò)誤提示和處理機(jī)制。

基于以上需求,我們可以使用C#的Socket編程實(shí)現(xiàn)一個(gè)文件上傳系統(tǒng),包括客戶端和服務(wù)端的程序。在程序中使用Socket進(jìn)行網(wǎng)絡(luò)連接和數(shù)據(jù)傳輸,同時(shí)對(duì)連接錯(cuò)誤和文件錯(cuò)誤進(jìn)行適當(dāng)處理和異常捕獲。

客戶端代碼和實(shí)現(xiàn)過程

dotnet new wpf -n "FileUploaderClient"

MainWindow.xaml:

<Window x:Class="FileUploaderClient.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="文件上傳客戶端" Height="350" Width="500">
    <Grid>
        <StackPanel Orientation="Vertical" HorizontalAlignment="Center" VerticalAlignment="Center">
            <TextBlock Text="選擇要上傳的文件:" Margin="0 0 0 10" />
            <Button Content="瀏覽..." Click="BrowseButton_Click" Width="80" Height="30" Margin="0 0 0 10" />
            <TextBox x:Name="FilePathTextBox" Text="{Binding FilePath}" Width="300" Height="30" Margin="0 0 0 10" />
            <TextBlock Text="輸入服務(wù)端IP地址:" Margin="0 0 0 10" />
            <TextBox x:Name="ServerIPTextBox" Text="{Binding ServerIP}" Width="200" Height="30" Margin="0 0 0 10" />
            <TextBlock Text="輸入服務(wù)端端口號(hào):" Margin="0 0 0 10" />
            <TextBox x:Name="ServerPortTextBox" Text="{Binding ServerPort}" Width="100" Height="30" Margin="0 0 0 10" />
            <Button Content="上傳" Click="UploadButton_Click" Width="80" Height="30" Margin="0 0 0 10" />
            <TextBlock x:Name="ResultTextBlock" Text="{Binding ResultMessage}" Margin="0 10" TextWrapping="Wrap" />
        </StackPanel>
    </Grid>
</Window>

MainWindow.xaml.cs:

using System;
using System.ComponentModel;
using System.IO;
using System.Net.Sockets;
using System.Security.Cryptography;
using System.Text;
using System.Windows;

namespace FileUploaderClient
{
    public partial class MainWindow : Window, INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        private string filePath;
        public string FilePath
        {
            get { return filePath; }
            set
            {
                filePath = value;
                OnPropertyChanged("FilePath");
            }
        }

        private string serverIP;
        public string ServerIP
        {
            get { return serverIP; }
            set
            {
                serverIP = value;
                OnPropertyChanged("ServerIP");
            }
        }

        private int serverPort;
        public int ServerPort
        {
            get { return serverPort; }
            set
            {
                serverPort = value;
                OnPropertyChanged("ServerPort");
            }
        }

        private string resultMessage;
        public string ResultMessage
        {
            get { return resultMessage; }
            set
            {
                resultMessage = value;
                OnPropertyChanged("ResultMessage");
            }
        }

        public MainWindow()
        {
            InitializeComponent();
            DataContext = this;
        }

        private void OnPropertyChanged(string propertyName)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }

        private void BrowseButton_Click(object sender, RoutedEventArgs e)
        {
            Microsoft.Win32.OpenFileDialog openFileDialog = new Microsoft.Win32.OpenFileDialog();
            if (openFileDialog.ShowDialog() == true)
            {
                FilePath = openFileDialog.FileName;
            }
        }

        private void UploadButton_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                // 讀取本地文件
                byte[] fileData = File.ReadAllBytes(FilePath);

                // 連接服務(wù)端并發(fā)送文件
                using (TcpClient client = new TcpClient(ServerIP, ServerPort))
                {
                    using (NetworkStream stream = client.GetStream())
                    {
                        // 發(fā)送文件名和文件長度
                        string fileName = Path.GetFileName(FilePath);
                        byte[] fileNameBytes = Encoding.UTF8.GetBytes(fileName);
                        byte[] fileNameLengthBytes = BitConverter.GetBytes(fileNameBytes.Length);
                        byte[] fileLengthBytes = BitConverter.GetBytes(fileData.Length);
                        stream.Write(fileNameLengthBytes, 0, 4);
                        stream.Write(fileNameBytes, 0, fileNameBytes.Length);
                        stream.Write(fileLengthBytes, 0, 4);

                        // 發(fā)送文件內(nèi)容
                        int bufferSize = 1024;
                        int bytesSent = 0;
                        while (bytesSent < fileData.Length)
                        {
                            int remainingBytes = fileData.Length - bytesSent;
                            int bytesToSend = Math.Min(bufferSize, remainingBytes);
                            stream.Write(fileData, bytesSent, bytesToSend);
                            bytesSent += bytesToSend;
                        }

                        ResultMessage = "文件上傳成功!";
                    }
                }
            }
            catch (Exception ex)
            {
                ResultMessage = "文件上傳失敗:" + ex.Message;
            }
        }
    }
}

使用該客戶端程序,用戶可以選擇本地文件進(jìn)行上傳,并輸入服務(wù)端的IP地址和端口號(hào)。客戶端會(huì)將選擇的文件發(fā)送給服務(wù)端進(jìn)行保存。

這個(gè)示例實(shí)現(xiàn)了基于TCP協(xié)議的文件上傳功能,使用TcpClient和NetworkStream進(jìn)行連接和數(shù)據(jù)傳輸。文件被分成較小的數(shù)據(jù)包進(jìn)行傳輸,發(fā)送前會(huì)計(jì)算文件名和文件長度,并通過4字節(jié)的長度前綴指示接收方應(yīng)該接收多少數(shù)據(jù)。

服務(wù)端代碼和實(shí)現(xiàn)過程

dotnet new wpf -n "FileUploaderServer"

MainWindow.xaml:

<Window x:Class="FileUploaderServer.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="文件上傳服務(wù)端" Height="350" Width="500">
    <Grid>
        <StackPanel Orientation="Vertical" HorizontalAlignment="Center" VerticalAlignment="Center">
            <TextBlock Text="輸入要監(jiān)聽的端口號(hào):" Margin="0 0 0 10" />
            <TextBox x:Name="PortTextBox" Text="{Binding Port}" Width="100" Height="30" Margin="0 0 0 10" />
            <Button Content="啟動(dòng)服務(wù)" Click="StartButton_Click" Width="80" Height="30" Margin="0 0 0 10" />
            <TextBlock x:Name="ResultTextBlock" Text="{Binding ResultMessage}" Margin="0 10" TextWrapping="Wrap" />
        </StackPanel>
    </Grid>
</Window>

MainWindow.xaml.cs:

using System;
using System.ComponentModel;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Security.Cryptography;
using System.Text;
using System.Threading;
using System.Windows;

namespace FileUploaderServer
{
    public partial class MainWindow : Window, INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        private int port;
        public int Port
        {
            get { return port; }
            set
            {
                port = value;
                OnPropertyChanged("Port");
            }
        }

        private string resultMessage;
        public string ResultMessage
        {
            get { return resultMessage; }
            set
            {
                resultMessage = value;
                OnPropertyChanged("ResultMessage");
            }
        }

        private TcpListener serverListener;
        private Thread serverThread;

        public MainWindow()
        {
            InitializeComponent();
            DataContext = this;
        }

        private void OnPropertyChanged(string propertyName)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }

        private void StartButton_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                // 啟動(dòng)服務(wù)端監(jiān)聽
                IPAddress ipAddress = IPAddress.Any;
                serverListener = new TcpListener(ipAddress, Port);
                serverListener.Start();

                // 啟動(dòng)服務(wù)端線程
                serverThread = new Thread(new ThreadStart(ServerThreadProc));
                serverThread.IsBackground = true;
                serverThread.Start();

                ResultMessage = "服務(wù)啟動(dòng)成功!";
            }
            catch (Exception ex)
            {
                ResultMessage = "服務(wù)啟動(dòng)失敗:" + ex.Message;
            }
        }

        private void ServerThreadProc()
        {
            while (true)
            {
                try
                {
                    // 接受客戶端連接請(qǐng)求
                    TcpClient client = serverListener.AcceptTcpClient();

                    // 處理客戶端連接請(qǐng)求
                    Thread clientThread = new Thread(new ParameterizedThreadStart(ClientThreadProc));
                    clientThread.IsBackground = true;
                    clientThread.Start(client);
                }
                catch (Exception)
                {
                    break;
                }
            }
        }

        private void ClientThreadProc(object parameter)
        {
            TcpClient client = (TcpClient)parameter;
            try
            {
                using (client)
                {
                    using (NetworkStream stream = client.GetStream())
                    {
                        // 讀取文件名和文件長度
                        byte[] fileNameLengthBytes = new byte[4];
                        stream.Read(fileNameLengthBytes, 0, 4);
                        int fileNameLength = BitConverter.ToInt32(fileNameLengthBytes, 0);
                        byte[] fileNameBytes = new byte[fileNameLength];
                        stream.Read(fileNameBytes, 0, fileNameLength);
                        string fileName = Encoding.UTF8.GetString(fileNameBytes);
                        byte[] fileLengthBytes = new byte[4];
                        stream.Read(fileLengthBytes, 0, 4);
                        int fileLength = BitConverter.ToInt32(fileLengthBytes, 0);

                        // 接收文件內(nèi)容
                        int bufferSize = 1024;
                        byte[] buffer = new byte[bufferSize];
                        int bytesRead = 0;
                        int totalBytesRead = 0;
                        byte[] fileData = new byte[fileLength];
                        while (totalBytesRead < fileLength && (bytesRead = stream.Read(buffer, 0, Math.Min(bufferSize, fileLength - totalBytesRead))) > 0)
                        {
                            Buffer.BlockCopy(buffer, 0, fileData, totalBytesRead, bytesRead);
                            totalBytesRead += bytesRead;
                        }
                        // 保存文件到本地
                        string savePath = Path.Combine(Environment.CurrentDirectory, "Uploads", fileName);
                        if (File.Exists(savePath))
                        {
                            savePath = Path.Combine(Environment.CurrentDirectory, "Uploads", Path.GetFileNameWithoutExtension(fileName) + "_" + DateTime.Now.ToString("yyyyMMddHHmmssfff") + Path.GetExtension(fileName));
                        }
                        using (FileStream fileStream = new FileStream(savePath, FileMode.CreateNew))
                        {
                            fileStream.Write(fileData, 0, fileLength);
                        }

                        ResultMessage = "文件保存成功:" + savePath;
                    }
                }
            }
            catch (Exception ex)
            {
                ResultMessage = "文件保存失敗:" + ex.Message;
            }
        }
    }
}

使用該服務(wù)端程序,用戶可以輸入要監(jiān)聽的端口號(hào),并啟動(dòng)服務(wù)端監(jiān)聽。當(dāng)有客戶端連接時(shí),服務(wù)端會(huì)接收文件數(shù)據(jù),并保存到指定位置。

這個(gè)示例實(shí)現(xiàn)了基于TCP協(xié)議的文件接收和保存功能,使用TcpListener和TcpClient進(jìn)行監(jiān)聽和連接,使用NetworkStream進(jìn)行數(shù)據(jù)傳輸。文件被分成較小的數(shù)據(jù)包進(jìn)行傳輸,發(fā)送前會(huì)計(jì)算文件名和文件長度,并通過4字節(jié)的長度前綴指示接收方應(yīng)該接收多少數(shù)據(jù)。

運(yùn)行結(jié)果

啟動(dòng)服務(wù)端,開啟端口12345。

啟動(dòng)客戶端程序,配置服務(wù)端地址。

責(zé)任編輯:姜華 來源: 今日頭條
相關(guān)推薦

2015-05-28 10:34:16

TCPsocket

2012-03-19 11:41:30

JavaSocket

2011-07-22 17:48:29

IOS Socket TCP

2009-11-24 13:15:35

Zend框架PHP上傳文件

2009-11-17 17:17:50

PHP上傳多個(gè)文件

2009-06-26 13:46:13

Struts

2015-04-24 09:48:59

TCPsocketsocket編程

2010-01-21 11:19:44

TCP Socketlinux

2009-10-27 16:18:58

VB.NET復(fù)制刪除文

2009-11-16 10:57:51

PHP上傳文件代碼

2019-09-18 20:07:06

AndroidTCP協(xié)議

2009-08-13 16:27:07

C#基于TCP協(xié)議

2009-07-14 17:20:31

Webwork文件上傳

2010-07-01 16:38:18

Linux TCP I

2009-07-21 14:49:55

XmlHttpRequ文件上傳進(jìn)度條

2010-03-03 16:19:29

Python Sock

2023-03-09 12:04:38

Spring文件校驗(yàn)

2015-03-03 13:47:34

HttpTCPIP

2009-11-16 10:16:24

PHP文件上傳

2024-06-11 00:00:01

用ReactGraphQLCRUD
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

主站蜘蛛池模板: 手机在线观看 | 毛片免费看 | 麻豆av在线 | 久久av在线播放 | 色综合久久88色综合天天 | www.精品一区 | 亚洲欧美一区二区三区1000 | 最新国产福利在线 | 久久精品国产亚洲a | 亚洲精选一区二区 | 91激情视频 | 男女免费视频网站 | 精品国产伦一区二区三区观看方式 | 国产精品综合网 | 国产福利在线 | 色呦呦网站 | 日本三级黄视频 | 国产精品久久精品 | 人人干人人看 | 精品乱人伦一区二区三区 | 久久另类视频 | www.se91 | 国产成视频在线观看 | 91精品免费视频 | 男女视频在线看 | 狠狠艹| 欧美精品一区二区免费 | 成人精品福利 | 日韩中文字幕2019 | 久久精品亚洲精品国产欧美 | 激情一区二区三区 | 91porn国产成人福利 | 伊人电影院av | 欧美国产中文字幕 | 中文字幕在线观看成人 | 国产精品毛片av | 国产中文在线 | 九九看片 | 中文字幕一区二区三区四区五区 | 久在线 | 国产精品一区二区视频 |