在使用Socket進行網絡程式設計的時候,一般都需要考慮一個包大小的問題。目前我們用得最大的情況是,每個包的大小為4KB(4096),但是,如果我們發送的資料要超過這個限制(這很常見),那麼應該怎麼辦呢?
Socket本身并不提供對于這種情況的實作,一般我們需要自己拆包群組裝。我下面寫了一個例子
下面是發送一個檔案的示範
服務端:
TcpListener server = null;
private void btListen_Click(object sender, EventArgs e)
{
ThreadStart info = new ThreadStart(StartListener);
Thread t = new Thread(info);
t.Start();
}
void StartListener()
server = new TcpListener(IPAddress.Any,8090);
try
{
server.Start();
while (true)
{
TcpClient client = server.AcceptTcpClient();
//直接給用戶端發送一個圖檔
byte[] request = new byte[256];
int i;
if ((i=client.Client.Receive(request)) != 0)
{
string path = Encoding.UTF8.GetString(request,0,i).Trim();
//發送大檔案
//1. 第一步:發送一個包,表示檔案的長度,讓用戶端知道後續要接收幾個包來重新組織成一個檔案
FileStream fs = new FileStream(path, FileMode.Open);
long length = fs.Length;
client.Client.Send(Encoding.UTF8.GetBytes(length.ToString()));
//2. 第二步:每次發送一個4KB的包,如果檔案較大,則會拆分為多個包
byte[] fileblock=new byte[4096];
while (fs.Read(fileblock,0,4096)!=0)
{
client.Client.Send(fileblock);
}
fs.Close();
}
}
}
catch (Exception ex)
MessageBox.Show(ex.Message);
}
用戶端
private void btTransfom_Click(object sender, EventArgs e)
{
TcpClient client = new TcpClient();
client.Connect("localhost", 8090);
string request = @"e:\temp\test.jpg";
client.Client.Send(Encoding.UTF8.GetBytes(request));
byte[] result = new byte[4096];
client.Client.Receive(result);//收取第一個包,裡面包含了檔案的長度資訊
int length = int.Parse(Encoding.UTF8.GetString(result));
byte[] file = new byte[4096];
int total = length;
MemoryStream ms = new MemoryStream();
while (total > 0)
{
int count = client.Client.Receive(file);
ms.Write(file, 0, count);
ms.Flush();
total -= count;
}
ms.Position = 0;
Bitmap bitmap = new Bitmap(ms);
pictureBox1.Image = bitmap;
}