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(); // } //} } }