如何通过Socket TCP发送并接收一个文件
展开全部
一.小结
1.大包发小包收,只发一次。
2.发时把文件扩展名,文件长度也随同一起发送,方便接收端接收时另存为正确的文件类型,并判断是否已经接收完毕。
如果不一起发送,分为文件扩展名,文件长度,文件内容,发送三次,在接收端,也可能会一起收到,反而不利于解析。
二.客户发送端代码
private void btnSend_Click(object sender, EventArgs e)
{
//组合出远程终结点
IPAddress ipAddress = IPAddress.Parse(this.txtIP3.Text);
IPEndPoint hostEP = new IPEndPoint(ipAddress, Convert.ToInt32(this.txtPort3.Text));
Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
try
{
socket.Connect(hostEP);
//1.发送用户协议
string path1 = Environment.CurrentDirectory; //获取应用程序的当前工作目录。
string doc = "YourSendFile.pdf";
string path = Path.Combine(path1, doc);
FileStream fs = File.Open(path, FileMode.Open);
//文件内容
byte[] bdata = new byte[fs.Length];
fs.Read(bdata, 0, bdata.Length);
fs.Close();
//文件扩展名,固定3字节
byte[] fileExtArray = Encoding.UTF8.GetBytes(string.Format("{0:D3}", currentDocExt));
//文件长度, 固定为20字节,前面会自动补零
byte[] fileLengthArray = Encoding.UTF8.GetBytes(bdata.Length.ToString("D20"));
//合并byte数组
byte[] fileArray = CombomBinaryArray(fileExtArray, fileLengthArray);
//合并byte数组
byte[] bdata1 = CombomBinaryArray(fileArray, bdata);
//发文件长度+文件内容
socket.Send(bdata1, bdata1.Length, 0);
//2.接收
//声明接收返回内容的字符串
string recvStr = "";
//声明字节数组,一次接收数据的长度为 1024 字节
byte[] recvBytes = new byte[1024];
//返回实际接收内容的字节数
int bytes = 0;
//循环读取,直到接收完所有数据
while (true)
{
bytes = socket.Receive(recvBytes, recvBytes.Length, 0);
//读取完成后退出循环
if (bytes <= 0) break;
//将读取的字节数转换为字符串
recvStr += Encoding.UTF8.GetString(recvBytes, 0, bytes);
}
//禁用 Socket
socket.Shutdown(SocketShutdown.Both);
//关闭 Socket
socket.Close();
//... do some busness logic ...
}
catch (Exception e1)
{
throw e1;
}
}
三.服务接收端代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.Net;
using System.Xml;
using System.Configuration;
using System.Windows.Forms;
using System.IO;
namespace ConsoleAppServer
{
class Program
{
[STAThread]
static void Main(string[] args)
{
bool Done = false;
IPAddress ipAddress = IPAddress.Parse(ConfigurationSettings.AppSettings["IP"].ToString());
IPEndPoint hostEP = new IPEndPoint(ipAddress, Convert.ToInt32(ConfigurationSettings.AppSettings["Port"]));
Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
socket.Bind(hostEP);
socket.Listen(3);
while (!Done)
{
Console.WriteLine("waiting for client");
Socket client = socket.Accept();
Console.WriteLine("connected client");
//1.接收
//声明字节数组,一次接收数据的长度为 1024 字节
byte[] recvBytes = new byte[1024];
//返回实际接收内容的字节数
int bytes = 0;
int FileLength = 0; // 900866;
int ReceivedLength = 0;
//1.0 接收文件扩展名
bytes = client.Receive(recvBytes, 3, 0);
string fileExt = Encoding.UTF8.GetString(recvBytes, 0, bytes);
string vFilePath = Environment.CurrentDirectory;
string vFileName = vFilePath + "\\Tmp" + Guid.NewGuid().ToString() + "." + fileExt;
//创建文件流,然后让文件流来根据路径创建一个文件
FileStream fs = new FileStream(vFileName, FileMode.Create);
//1.1 接收文件长度
bytes = client.Receive(recvBytes, 20, 0);
//将读取的字节数转换为字符串
string fileLength = Encoding.UTF8.GetString(recvBytes, 0, bytes);
FileLength = Convert.ToInt32(fileLength);
//1.2接收文件内容
while (ReceivedLength < FileLength)
{
bytes = client.Receive(recvBytes, recvBytes.Length, 0);
ReceivedLength += bytes;
fs.Write(recvBytes, 0, bytes);
}
fs.Flush();
fs.Close();
//... do some business logic ...
string returnData = SomeBusinessLogic();
//2.发送
byte[] bdata = Encoding.UTF8.GetBytes(returnData);
client.Send(bdata, bdata.Length, 0);
client.Close();
}
socket.Shutdown(SocketShutdown.Both);
socket.Close();
}
}
}
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询