基于Socket通信的BS结构文件服务器客户端的简易程序(2)

来源:互联网 发布:海川新盟软件下载 编辑:程序博客网 时间:2024/06/04 18:03

http://blog.csdn.net/weixingstudio/article/details/7042266

 

下面是客户端的所有代码,整个程序的源码下载连接会在下一篇给出。

 

using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using System.Drawing;using System.Linq;using System.Text;using System.Windows.Forms;using System.Net.Sockets;using System.Threading;using System.Runtime.Serialization;using System.Runtime.Serialization.Formatters.Binary;using System.IO;using System.Collections.Specialized;namespace Client{    public partial class MainForm : Form    {        // 服务器和客户机协约的通信协议        // "00" 同意连接        // "01" 拒绝连接        // "10" 用户请求离线        // "11" 通知用户刷新在线用户列表        // "12" 请求在线用户列表        // ""        private string userName;        private NetworkStream netStream = null;        private Thread receiveThread = null;        private int maxBuffer = 1024 * 1024; // 最大文件1M        private int fileBuffer_eachTime_sended = 8 * 1024;// 每次最多传送8K , 先这样测测        private delegate void setOnlineuserDelegate(string s);        private delegate void flashFileListDelegate(StringCollection sc);        //private byte[] file_byte;        // 添加一个变量,用来标识窗口是不是第一次启动,并且需要刷新文件列表        private bool isFlashFilesNeeded = true;        public MainForm(string user_Name, NetworkStream networkStream)        {            InitializeComponent();            userName = user_Name;            netStream = networkStream; // 通过窗口间的参数传递来传递用来给Socket通信用的NetwokStream            this.FormClosed += new FormClosedEventHandler(MainForm_FormClosed);            receiveThread = new Thread(new ThreadStart(receive));            //receiveThread.ApartmentState = ApartmentState.STA;            //Thread.CurrentThread.SetApartmentState(ApartmentState.STA);            receiveThread.SetApartmentState(ApartmentState.STA);            // 开启接收信息线程            receiveThread.Start();        }        /// <summary>        /// 客户端接收信息的处理函数        /// </summary>        private void receive()        {            // 初始化在线用户列表,给服务器发送一个请求在线用户列表命令            netStream.Write(new byte[] { 1, 2 }, 0, 2);            // 通过循环操作不停的和服务器进行通信            while(true)            {                byte[] cmd = new byte[4];                netStream.Read(cmd,0,cmd.Length);                string command = DecodingBytes(cmd);                switch(command)                {                    // 服务器发送用户请求连线命令,没有实际意义                    case "10":                        {                            break;                        }                    // 通知用户刷新在线用户列表                    case "11":                        {                            //先发送了一个命令,然后发送在线用户列表的信息                            byte[] onlineUserListBuffer=new byte[maxBuffer];                            int byteCnt = netStream.Read(onlineUserListBuffer, 0, onlineUserListBuffer.Length);                            // 进行反序列化                            IFormatter format = new BinaryFormatter();                            MemoryStream stream = new MemoryStream();                            stream.Write(onlineUserListBuffer, 0, byteCnt);                            stream.Position = 0;                            StringCollection onlineList = (StringCollection)format.Deserialize(stream);                            // 清空原始信息                            string temp = "";                            // 线程安全的清空控件中的文本信息                            clearOnLineUserList(temp);                            foreach (string onliner in onlineList)                            {                                // 线程安全的给控件添加信息                                flashOnlineUser(onliner);                            }                            // 通过判断刷新文件列表                            if (isFlashFilesNeeded)                            {                                // 请求文件列表                                netStream.Write(new byte[] { 4, 4 }, 0, 2);                                isFlashFilesNeeded = false;                            }                            break;                        }                    // 服务器通知客户端有人上线                    case "22":                        {                            byte[] buffer=new byte[64];                            netStream.Read(buffer,0,buffer.Length);                            string info = Encoding.Unicode.GetString(buffer).TrimEnd('\0');                            this.toolStripStatusLabel1.Text = info;                            // 有人上线以后需要刷新在线用户列表                            netStream.Write(new byte[] { 1, 2 }, 0, 2);                            break;                        }                    // 服务器通知客户端有用户离线                    case "23":                        {                            byte[] buffer = new byte[64];                            netStream.Read(buffer, 0, buffer.Length);                            string info = Encoding.Unicode.GetString(buffer).TrimEnd('\0');                            this.toolStripStatusLabel1.Text = info;                            // 有人离线后需要刷新在线用户列表                            netStream.Write(new byte[] { 1, 2 }, 0, 2);                            break;                        }                    // 服务器通知文件上传成功                    case "34":                        {                            //Thread.Sleep(50);                            MessageBox.Show("文件上传成功!");                            // 刷新文件列表                            netStream.Write(new byte[] { 4, 4 }, 0, 2);                            break;                        }                    // 服务器给用户返回文件列表                    case "45":                        {                            byte[] buffer=new byte[8196];                            int byteCnt = netStream.Read(buffer, 0, buffer.Length);                            // 文件列表的反序列化                            IFormatter format = new BinaryFormatter();                            MemoryStream stream = new MemoryStream();                            stream.Write(buffer, 0, byteCnt);                            stream.Position = 0;                            // 下列代码已执行                            StringCollection fileList = (StringCollection)format.Deserialize(stream);                            // 线程安全的给控件添加信息                            flashFileList(fileList);                            break;                        }                    // 服务器给用户传送文件                    case "56":                        {                            byte[] buffer = new byte[fileBuffer_eachTime_sended]; // 每次传送的次数                            SaveFileDialog sFD = new SaveFileDialog();                            sFD.Filter = "txt files(*.txt)|*.txt|Image Files(*.BMP;*.JPG;*.GIF)|*.BMP;*.JPG;*.GIF|All files(*.*)|*.*";                            if (sFD.ShowDialog() == DialogResult.OK)                            {                                string fileName = sFD.FileName;                                //MessageBox.Show(fileName);                                // 保存文件                                FileStream file = File.Open(fileName, FileMode.Create);                                BinaryWriter bw = new BinaryWriter(file);                                //// 接收需要发送的次数                                //byte[] receive_num=new byte[8];                                //netStream.Read(receive_num, 0, 8);                                //string temp_receive_num = Encoding.Unicode.GetString(receive_num).TrimEnd('\0');                                byte[] sumFile_byte = new byte[16];                                // 接收总的文件大小                                netStream.Read(sumFile_byte, 0, sumFile_byte.Length);                                string t = Encoding.Unicode.GetString(sumFile_byte).TrimEnd('\0');                                string tt = t;                                char[] xyz=tt.ToCharArray();                                int count = 0;                                foreach (char c in xyz)                                {                                    if (c >= '0' && c <= '9')                                    {                                        count++;                                    }                                }                                tt = tt.Substring(0,count);                                long fileSize = Convert.ToInt64(tt,10);                                int receive_number_int = (int)(fileSize / fileBuffer_eachTime_sended) + 1;                                // 向文件中写数据                                if (receive_number_int == 1)                                {                                    // 只需要传送一次                                    int FileSize = netStream.Read(buffer, 0, fileBuffer_eachTime_sended);                                    //int FileSize = clientSocket.Receive(fileBuffer);                                    bw.Write(buffer, 0, FileSize);                                    bw.Flush();                                 }                                else if (receive_number_int > 1)                                {                                    // 需要多次接收文件                                    for (int i = 1; i < receive_number_int; i++)                                    {                                        netStream.Read(buffer, 0, fileBuffer_eachTime_sended);                                        //clientSocket.Receive(fileBuffer);                                        bw.Write(buffer, 0, fileBuffer_eachTime_sended);                                        bw.Flush();                                    }                                    // 计算最后需要接收的字节数                                    int num_remain = (int)(fileSize % fileBuffer_eachTime_sended);                                    byte[] newBuffer = new byte[num_remain];                                    netStream.Read(newBuffer, 0, num_remain);                                    bw.Write(newBuffer, 0, num_remain);                                    bw.Flush();                                }                                // 向文件中写数据                                bw.Close();                                file.Close();                            }                            break;                        }                    // 删除文件成功                    case "67":                        {                            MessageBox.Show("删除文件成功");                            // 刷新文件列表                            netStream.Write(new byte[] { 4, 4 }, 0, 2);                            break;                         }                }            }        }        /// <summary>        /// 线程安全的在控件中显示文件列表        /// </summary>        /// <param name="sc"></param>        private void flashFileList(StringCollection sc)        {            if (this.listView1.InvokeRequired)            {                flashFileListDelegate call = delegate(StringCollection t)                {                    // 清空以前的                    this.listView1.Items.Clear();                    int length = t.Count;                    string[] fileInfo = new string[length];                    int i = 0;                    foreach (string s in t)                    {                        fileInfo[i] = s;                        i++;                    }                    i = 1;                    // 计算每一行,一共有多少行                    for (i = 0; i < length / 3; i++)                    {                        ListViewItem lvi = new ListViewItem();                        lvi.Text = fileInfo[i * 3];                        lvi.SubItems.Add(fileInfo[i * 3 + 1]);                        lvi.SubItems.Add(fileInfo[i * 3 + 2]);                        this.listView1.Items.Add(lvi);                    }                };                this.listView1.Invoke(call, sc);            }            else            {                // 清空以前的                this.listView1.Clear();                int length = sc.Count;                string[] fileInfo = new string[length];                int i = 0;                foreach (string s in sc)                {                    fileInfo[i] = s;                    i++;                }                i = 1;                // 计算每一行,一共有多少行                for (i = 0; i < length / 3; i++)                {                    ListViewItem lvi = new ListViewItem();                    lvi.Text = fileInfo[i];                    lvi.SubItems.Add(fileInfo[i + 1]);                    lvi.SubItems.Add(fileInfo[i + 2]);                    this.listView1.Items.Add(lvi);                }            }        }        /// <summary>        /// 线程安全的清空控件信息        /// </summary>        /// <param name="s"></param>        private void clearOnLineUserList(string s)        {            if (this.userList.InvokeRequired)            {                setOnlineuserDelegate call = delegate(string ss) { this.userList.Text = ss; };                this.userList.Invoke(call, s);            }            else            {                this.userList.Text = s;            }        }        private void flashOnlineUser(string userName)        {            if (this.userList.InvokeRequired)            {                setOnlineuserDelegate call = delegate(string s) { this.userList.Text += s + "\n"; };                this.userList.Invoke(call, userName);            }            else            {                this.userList.Text += "\n" + userName;            }        }        private string DecodingBytes(byte[] s)        {            return string.Concat(s[0].ToString(), s[1].ToString());        }        /// <summary>        /// 关闭窗口之前判断连接是否断开,如果连接没有断开则调用关闭连接的服务        /// </summary>        /// <param name="sender"></param>        /// <param name="e"></param>        void MainForm_FormClosed(object sender, FormClosedEventArgs e)        {            //throw new NotImplementedException();            if (netStream == null)            {                //关闭父窗口及自身===========                this.Owner.Close();                this.Close();            }            else            {                // 先关闭网络流,在关闭窗口                // 给服务器发送断开连接请求                DialogResult ret;                ret = MessageBox.Show("确定与服务器断开连接吗?",                                        "退出",                                        MessageBoxButtons.OKCancel,                                        MessageBoxIcon.Question,                                        MessageBoxDefaultButton.Button2);                if (ret == DialogResult.OK)                {                    //向服务器发送离线请求                    netStream.Write(new byte[] { 1, 0 }, 0, 2);                    if (receiveThread != null)                    {                        // 终止接受信息进程                        receiveThread.Abort();                        receiveThread = null;                    }                    // 关闭网络流连接                    netStream.Close();                    //关闭父窗口及自身===========                    //this.Owner.Close();                    //this.Close();                }                else                { }            }        }        private void MainForm_Load(object sender, EventArgs e)        {            toolStripStatusLabel1.Text = "welcome to use this system! Developped by WeiSONG";            Thread.CurrentThread.SetApartmentState(ApartmentState.STA);        }        private void button1_Click(object sender, EventArgs e)        {            if (this.openFileDialog1.ShowDialog() == DialogResult.OK)            {                try                {                    string filePath = openFileDialog1.FileName;                    //MessageBox.Show(filePath);                    FileStream fs = File.Open(filePath, FileMode.Open);                    long fileSize = fs.Length;                    // 如果文件大小超过规定的值,则弹出提示消息,退出操作                    if (fileSize >= maxBuffer)                    {                        MessageBox.Show("对不起,您选择上传的文件过大,本系统暂时不支持!", "INFO");                        return;                    }                    // 计算需要发送的次数                    int times_tobesended = (int)fileSize / fileBuffer_eachTime_sended + 1;                    BinaryReader br = new BinaryReader(fs);                    // 用来存储即将发送的数据                    byte[] bytes_tobesend = new byte[fileBuffer_eachTime_sended];                    // 获取文件名                    string[] temp = filePath.Split('\\');                    int k = temp.Length;                    string fileName = temp[k - 1];                    //MessageBox.Show(fileName);                    // 给服务器发送上传文件请求                    netStream.Write(new byte[] { 3, 3 }, 0, 2);                    netStream.Flush();                    // 给服务器发送要传送的文件名                    netStream.Write(Encoding.Unicode.GetBytes(fileName), 0, Encoding.Unicode.GetBytes(fileName).Length);                    // 给服务器传送需要文件发送的次数                    //netStream.Write(Encoding.Unicode.GetBytes(times_tobesended.ToString()), 0, Encoding.Unicode.GetBytes(times_tobesended.ToString()).Length);                    // 给服务器发送总的文件大小                    netStream.Write(Encoding.Unicode.GetBytes(fileSize.ToString()), 0, Encoding.Unicode.GetBytes(fileSize.ToString()).Length);                    // 开始传送文件                    if (times_tobesended == 1)                    {                        // 只需要传送一次                        byte[] bytes_Only1time=new byte[fileSize];                        br.Read(bytes_Only1time, 0, (int)fileSize);                        netStream.Write(bytes_Only1time, 0, (int)fileSize);                    }                    else if (times_tobesended > 1)                    {                        // 需要传送的次数>1, 需要分多次传送                        for (int i = 1; i < times_tobesended; i++)                        {                            bytes_tobesend = br.ReadBytes(fileBuffer_eachTime_sended);                            //br.Read(bytes_tobesend, 0, fileBuffer_eachTime_sended);                            netStream.Write(bytes_tobesend,0,fileBuffer_eachTime_sended);                            netStream.Flush();                            Thread.Sleep(10);                        }                        // 最后一次传送所有剩余的字节                        int remainedBytes = (int)(fileSize % fileBuffer_eachTime_sended); // 计算剩余的字节数                         byte[] to_be_send_remain = new byte[remainedBytes];                        to_be_send_remain = br.ReadBytes(remainedBytes);                        //br.Read(bytes_tobesend, 0, remainedBytes);                        netStream.Write(to_be_send_remain, 0, remainedBytes);                        netStream.Flush();                        //Thread.Sleep(10);                    }                     br.Close();                    fs.Close();                }                catch(FileLoadException)                {                    //                }            }        }        private void button2_Click(object sender, EventArgs e)        {            //  请求文件列表            netStream.Write(new byte[] { 4, 4 }, 0, 2);            netStream.Flush();            // 获取选中的行            //string test = this.listView1.SelectedItems[0].Text;            //MessageBox.Show(test);            ////this.listView1.Items.Add("test","aaa","bbb");            //ListViewItem lvi = new ListViewItem();            //lvi.Text = "第一列信息";            //lvi.SubItems.Add("第二列");            //this.listView1.Items.Add(lvi);            //ListViewItem lv2 = new ListViewItem();            //lv2.Text = "第二列信息";            //this.listView1.Items.Add(lv2);        }        private void listView1_SelectedIndexChanged(object sender, EventArgs e)        {            //        }        private void button3_Click(object sender, EventArgs e)        {            if (this.listView1.SelectedItems.Count == 0)            {                MessageBox.Show("请选择好文件以后在选择下载");            }            else            {                string fileName = this.listView1.SelectedItems[0].Text; // 获取选择的文件名                // 给服务器发送下载文件请求                netStream.Write(new byte[] { 5, 5 }, 0, 2);                byte[] fileName_byte = Encoding.Unicode.GetBytes(fileName);                // 发送要下载的文件名                netStream.Write(fileName_byte, 0, fileName_byte.Length);            }        }        private void button4_Click(object sender, EventArgs e)        {            if (this.listView1.SelectedItems.Count == 0)            {                MessageBox.Show("请选择好文件以后在选择删除");            }            else            {                string fileName = this.listView1.SelectedItems[0].Text;                byte[] fileName_byte = Encoding.Unicode.GetBytes(fileName);                // 先发送请求指令                netStream.Write(new byte[] { 6, 6 }, 0, 2);                // 发送文件名                netStream.Write(fileName_byte, 0, fileName_byte.Length);            }        }        //private void disconnectToolStripMenuItem_Click(object sender, EventArgs e)        //{        //    // 给服务器发送断开连接请求        //    DialogResult ret;        //    ret = MessageBox.Show("确定与服务器断开连接吗?",        //                          "退出",        //                          MessageBoxButtons.OKCancel,        //                          MessageBoxIcon.Question,        //                          MessageBoxDefaultButton.Button2);        //    if (ret == DialogResult.OK)        //    {        //        //向服务器发送离线请求        //        netStream.Write(new byte[] { 1, 0 }, 0, 2);        //        if (receiveThread != null)        //        {        //            // 终止接受信息进程        //            receiveThread.Abort();        //        }        //        // 关闭网络流连接        //        netStream.Close();        //        //关闭父窗口及自身===========        //        this.Owner.Close();        //        this.Close();        //    }        //}    }}