本文介绍客户端和服务器之间传送文件的方法。
首先,我们需要明确:网络上传送的是二进制流。当接收方收到发送方传过来的数据时,需要判断收到的是文本还是文件。类型不同,处理方式也不同。收到文本,则显示在对话框中。收到文件,则弹出保存按钮,保存文件。
可以在二进制流中的第一位设置标记位:0表示文本,1表示文件(未来还可以扩展,2表示震动,3表示语音等等)。
public enum InformationType
{
Message = 0,
File = 1
}
1.发送方
1.1 发送文本
//发送文本
private void button1_Click(object sender, EventArgs e)
{
byte[] buffer = Encoding.UTF8.GetBytes(writeBox.Text);
List<byte> newBuffer = new List<byte>();
newBuffer.Add((byte)InformationType.Message); //设置标志位
newBuffer.AddRange(buffer);
string ip = comboBox1.SelectedItem.ToString(); //获取用户在下拉框中选择的IP地址
clientDic[ip].Send(newBuffer.ToArray()); //发送
showBox.Text += writeBox.Text + "\r\n";
writeBox.Text = "";
}
1.2 发送文件
//发送文件
private void button2_Click(object sender, EventArgs e)
{
OpenFileDialog fileDialog = new OpenFileDialog();
fileDialog.InitialDirectory = @"C:\Users\liyz-b\Desktop";
fileDialog.Title = "选择文件";
fileDialog.Filter = "所有文件|*.*";
fileDialog.ShowDialog();
string path = fileDialog.FileName;
using (FileStream fsRead = new FileStream(path, FileMode.Open, FileAccess.Read))
{
byte[] buffer = new byte[1024 * 1024];
int length = fsRead.Read(buffer, 0, buffer.Length);
List<byte> newBuffer = new List<byte>();
newBuffer.Add((byte)InformationType.File); //设置标志位
newBuffer.AddRange(buffer);
string ip = comboBox1.SelectedItem.ToString(); //获取用户在下拉框中选择的IP地址
clientDic[ip].Send(newBuffer.ToArray(), 0, length + 1, SocketFlags.None);
}
}
2.接收方
收到文本,则显示在对话框中。收到文件,则弹出保存按钮,保存文件。
void socketReceive()
{
while (true)
{
try
{
byte[] data = new byte[1024 * 1024];
int length = client.Receive(data); //length表示接收到的数据的长度
if (length == 0)
break;
if (data[0] == (byte)InformationType.Message)
{
string message = Encoding.UTF8.GetString(data, 1, length-1);
showBox.Text += client.RemoteEndPoint.ToString() + ":" + message + "\r\n";
}
else if (data[0] == (byte)InformationType.File)
{
SaveFileDialog saveFile = new SaveFileDialog();
saveFile.InitialDirectory = @"C:\Users\liyz-b\Desktop";
saveFile.Title = "保存文件";
saveFile.Filter = "所有文件|*.*";
saveFile.ShowDialog(this);
string path = saveFile.FileName;
using (FileStream fsWrite = new FileStream(path, FileMode.OpenOrCreate, FileAccess.Write))
{
fsWrite.Write(data, 1, length - 1);
}
}
}
catch
{
}
}
}
3.分析
当需要传送的文件很大时,需要分块传输。以后的文章中,会详细分析分块传输的问题。