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