Socket编程(五)- 传送文件

    本文介绍客户端和服务器之间传送文件的方法。

    首先,我们需要明确:网络上传送的是二进制流。当接收方收到发送方传过来的数据时,需要判断收到的是文本还是文件。类型不同,处理方式也不同。收到文本,则显示在对话框中。收到文件,则弹出保存按钮,保存文件。

    可以在二进制流中的第一位设置标记位: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.分析

    当需要传送的文件很大时,需要分块传输。以后的文章中,会详细分析分块传输的问题。

猜你喜欢

转载自blog.csdn.net/liyazhen2011/article/details/88232895