65.9K
CodeProject 正在变化。 阅读更多。
Home

C# .NET 2.0 中使用 Socket 应用程序进行文件传输

starIconstarIcon
emptyStarIcon
starIcon
emptyStarIconemptyStarIcon

2.32/5 (41投票s)

2008年3月1日

CPL

2分钟阅读

viewsIcon

434716

downloadIcon

25358

使用 C#.NET 通过 TCP Socket 进行文件传输

简介与背景

当我尝试学习 .NET (C#) 中的 Socket 应用程序时,我没有找到任何好的现成的 Socket 代码来学习。 我遇到了一个问题,为此,我专门建立了一个关于 Socket 应用程序的博客。 在这里我只给出一个应用程序,但在我的博客中,我有一些代码示例来学习 C#.NET 中的 Socket。 您可以在我的博客上找到长期实用的 C# 代码:www.socketprogramming.blogspot.com

我编写了代码来使用 C#.NET Socket 应用程序将文件从客户端传输到服务器。 该代码使用 TCP 协议发送文件,可以在 LAN 和 WAN(互联网)中运行。 它可以将小文件从客户端发送到服务器,我已经用 1.5MB 文件测试过。 但是任何人都可以修改该代码,并构建一个应用程序,通过单个服务器支持多个客户端来发送大型文件。

我将概述/步骤来制作一个 Socket 应用程序。 在这里,有两个应用程序:一个是服务器,另一个是客户端。 首先,服务器将打开一个端口并等待来自客户端的请求,客户端将尝试连接到服务器。 收到连接请求后,服务器将接受它并建立成功的连接。 建立成功的连接后,客户端将以字节数组形式发送数据,服务器将捕获并保存它。 然后,它将保存这些字节。 成功传输数据后,服务器将保存数据并断开客户端连接。

我认为在阅读此代码后,人们可以理解 Socket 应用程序的工作原理。 如果有人无法理解,我请求他们阅读我的博客。 如果您仍然有任何问题,请通过博客评论/邮件与我联系,我将回复。

Using the Code

完整的服务器和客户端代码都在压缩格式文件中。 您可以下载并使用它。 我将给出服务器和客户端的两个代码块。

带有注释的服务器应用程序的核心代码如下所示

//FILE TRANSFER USING C#.NET SOCKET - SERVER
class FTServerCode
{
    IPEndPoint ipEnd; 
    Socket sock;
    public FTServerCode()
    {
        ipEnd = new IPEndPoint(IPAddress.Any, 5656); 
        //Make IP end point to accept any IP address with port no 5656.
        sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);
        //Here creating new socket object with protocol type and transfer data type
        sock.Bind(ipEnd); 
        //Bind end point with newly created socket.
    }
    public static string receivedPath;
    public static string curMsg = "Stopped";
    public void StartServer()
    {
        try
        {
            curMsg = "Starting...";
            sock.Listen(100);
            /* That socket object can handle maximum 100 client connection at a time & 
            waiting for new client connection /
            curMsg = "Running and waiting to receive file.";
            Socket clientSock = sock.Accept();
            /* When request comes from client that accept it and return 
            new socket object for handle that client. */
            byte[] clientData = new byte[1024 * 5000];
            int receivedBytesLen = clientSock.Receive(clientData);
            curMsg = "Receiving data...";    
            int fileNameLen = BitConverter.ToInt32(clientData, 0); 
            /* I've sent byte array data from client in that format like 
            [file name length in byte][file name] [file data], so need to know 
            first how long the file name is. /
            string fileName = Encoding.ASCII.GetString(clientData, 4, fileNameLen);
            /* Read file name */
            BinaryWriter bWrite = new BinaryWriter(File.Open
		(receivedPath +"/"+ fileName, FileMode.Append)); ; 
            /* Make a Binary stream writer to saving the receiving data from client. /
            bWrite.Write(clientData, 4 + fileNameLen, 
		receivedBytesLen - 4 - fileNameLen);
            /* Read remain data (which is file content) and 
            save it by using binary writer. */
            curMsg = "Saving file...";
            bWrite.Close();
            clientSock.Close(); 
            /* Close binary writer and client socket */
            curMsg = "Received & Saved file; Server Stopped.";
        }
        catch (Exception ex)
        {
            curMsg = "File Receiving error.";
        }
    }
} 

客户端应用程序的代码如下所示

//FILE TRANSFER USING C#.NET SOCKET - CLIENT
class FTClientCode
{
    public static string curMsg = "Idle";
    public static void SendFile(string fileName)
    {
        try
        {
             IPAddress[] ipAddress = Dns.GetHostAddresses("localhost");
             IPEndPoint ipEnd = new IPEndPoint(ipAddress[0], 5656); 
             /* Make IP end point same as Server. */
             Socket clientSock = new Socket(AddressFamily.InterNetwork, 
		SocketType.Stream, ProtocolType.IP);
             /* Make a client socket to send data to server. */
             string filePath = "";
             /* File reading operation. */
             fileName = fileName.Replace("\\", "/");
             while (fileName.IndexOf("/") > -1)
             {
                 filePath += fileName.Substring(0, fileName.IndexOf("/") + 1);
                 fileName = fileName.Substring(fileName.IndexOf("/") + 1);
             }         
             byte[] fileNameByte = Encoding.ASCII.GetBytes(fileName);
             if (fileNameByte.Length > 850 * 1024)
             {
                 curMsg = "File size is more than 850kb, please try with small file.";
                 return;
             }
             curMsg = "Buffering ...";
             byte[] fileData = File.ReadAllBytes(filePath + fileName); 
             /* Read & store file byte data in byte array. */
             byte[] clientData = new byte[4 + fileNameByte.Length + fileData.Length]; 
             /* clientData will store complete bytes which will store file name length, 
             file name & file data. */
             byte[] fileNameLen = BitConverter.GetBytes(fileNameByte.Length);
             /* File name length’s binary data. */
             fileNameLen.CopyTo(clientData, 0);
             fileNameByte.CopyTo(clientData, 4);
             fileData.CopyTo(clientData, 4 + fileNameByte.Length);
             /* copy these bytes to a variable with format line [file name length]
             [file name] [ file content] */
             curMsg = "Connection to server ...";
             clientSock.Connect(ipEnd); 
             /* Trying to connection with server. /
             curMsg = "File sending...";
             clientSock.Send(clientData);
             /* Now connection established, send client data to server. */
             curMsg = "Disconnecting...";
             clientSock.Close(); 
             /* Data send complete now close socket. */
             curMsg = "File transferred.";
        }
        catch (Exception ex)
        {
             if(ex.Message=="No connection could be made because the target machine 
                actively refused it")
                 curMsg="File Sending fail. Because server not running." ;
             else
                 curMsg = "File Sending fail." + ex.Message;
        } 
    }
} 

我希望您了解如何在 C# 中通过 TCP Socket 将文件从客户端发送到服务器。 这里我编写了简单的代码来发送单个文件,但它是基本代码。 通过修改该代码,可以将多个文件从客户端发送到服务器,并且通过结合线程技术,该服务器可以一次处理多个客户端。 通过使用两端的二进制写入器和读取器,也可以发送大型文件。 在这里,我们将给出一个关于 TCP 缓冲区溢出的问题,需要分片后发送数据。 要了解更多关于 Socket 编程的信息,请访问我的博客:http://socketprogramming.blogspot.com/

© . All rights reserved.