飞鸽传书
课题设计任务书
姓 名
题 目 类似飞鸽传书的局域网
设计一个在局域网内部聊天的软件,类似于QQ用户之间的聊天,具有文字聊天,传文件,
文件夹,的功能,便于用户之间的交流,开发主要功能包括:
1( 局域网内系统,它在局域网内选择相应的用户,以便对之发送文字信息。
2( 上线提醒,即时提醒并显示在线用户上线好友
设 3( 修改昵称,在TEXTBOX中输入修改的名称,点击右键,确定,就会在好友列表上即时显计
示修改后的名称,更便于好友的查找,交流。 任
务 2(文件,文件夹传输系统,它是在先把需要传输的文件,文件夹转换成相应的数据流传输,
到了目的主机再由之还原。本系统的文字聊天系统实现的功能类似于QQ用户之间的聊天
开发工具:Microsoft Visual Studio 2005
第17周(2011.8.29~2011.9.4):按照老师的指导,讨论项目需求和所要实现的功能,写出课
题的计划书并进行任务规划,根据数据库设计划分功能模块,对项目进行分工,划分各自任
务。
时 第18周(2011.9.5~2011.9.11):主要是对系统的测试,以及纠错,加强对软件的功能设计,间
添补遗漏;界面在最后一周做了很大的变动,使之更加完善,简化了管理的操作,且更加的进
度 清晰明了,写出初步的文档。。
第19周(2011.9.12~2011.9.16):调试成功后,经过老师的再次检验,经过讨论后,对个别功
能进行逐步细化和改善,最后进行整理,将程序上交给老师验收,通过后,完成文档。
[01]马煜,陈海军,朱朝阳,Visual C#.NET案例开发锦集,电子工业出版社, 2008.4
[02]李春葆、谭成予、金晶、曾平,C#程序设计教程,北京:清华大学出版社,2010.1 原 主
始 要
资 参
料 考
与 文
献
指导教师签字: 年 月 日
摘 要
网络通讯在当今已经不算新鲜事物,随着计算机网络技术的发展,各种各样基于网络的应用也随之诞生,比如基于互联网的信息发布,通信,数据共享等等局域网的发展也同样迅速,很多政府机构,企业,学校,都是先以一个统一的局域网连接在一起,再分别接入INTERNET,因为大多数网络通讯都需要借助INTERNET上的服务器,这就给那些具有大规模内部网络的用户造成了许多问题,如浪费网络资源,遭遇到网络攻击,传播的病毒,破坏防御系统等等。由于互联网上的网络通讯工具给企业内部信息交流带来了不便,所以为了方便内部网络用户之间的沟通,需要开发一个基于局域网的信息收发系统的即时通讯工具,是现在内部网络中进行信息的交流。本课题设计主要针对局域网通讯而开发设计的,采用的是C/S构架,类似飞鸽传输系统,来实现聊天,文件传输功能,并借助一些网络通讯组件。成功的实现了再局域网上的即时通讯。
本论文的目标是设计一个类似飞鸽传输的局域网通信软件,并分析它在其领域的优势。本论文以C编写。能在windows2000/net/xp登环境下运行。设计共分为五大模块,分别是:首先,介绍选题背景及意义和国内外研究现状;其次,介绍TCP/IP点对点协议技术,C/S架构和SOCKET网络编程技术;再次,对当前局域网文件传输进行需求分析并提出解决
方案
气瓶 现场处置方案 .pdf气瓶 现场处置方案 .doc见习基地管理方案.doc关于群访事件的化解方案建筑工地扬尘治理专项方案下载
;然后,根据解决方案对系统进行设计,最后对
工作计划
幼儿园家访工作计划关于小学学校工作计划班级工作计划中职财务部门工作计划下载关于学校后勤工作计划
统计以及分析系统进行测试并得到测试结果。
关键词:聊天;传输;socket;飞鸽传书;C/S结构;
目 录
摘 要 ....................................................................................................................................... 1
第1章 项目分析 ...................................................................................................................... 1 1.1问题描述 .......................................................................................................................... 1 1.2技术分析 .......................................................................................................................... 1 第2章 系统功能设计与实现 ................................................................................................... 3 3.1系统目标设计 .................................................................................................................. 3 3.2整体E-R图 ...................................................................................................................... 3
3.2.2关系设计 ................................................................................................................... 3 第3章 实现 .............................................................................................................................. 3
3.1上线提醒模块 .................................................................................................................. 3
3.1.1界面 ........................................................................................................................... 4
3.1.3实现过程 ................................................................................................................... 6 3.2 文字聊天模块 .................................................................................................................. 6
3.2.1界面 ........................................................................................................................... 6
3.2.2代码 ........................................................................................................................... 6
3.2.3实现过程 ................................................................................................................... 8 3.3传文件模块 ...................................................................................................................... 8
3.3.1界面 ........................................................................................................................... 8
3.3.2代码 ........................................................................................................................... 8
3.3.3实现过程 ................................................................................................................. 12 3.4昵称修改模块 ................................................................................................................ 12
3.4.1界面 ......................................................................................................................... 12
3.4.2代码 ......................................................................................................................... 12
3.4.3实现过程 ................................................................................................................. 14 3.5传文件夹模块 ................................................................................................................ 14
3.5.1界面 ......................................................................................................................... 15
3.5.2代码 ......................................................................................................................... 15
3.5.3实现过程 ................................................................................................................. 19 第4章 结束语 ........................................................................................................................ 20 附录B: 主要源程序 ............................................................................................................... 23
飞鸽传书
第1章 项目分析
1.1问题描述
当时间走向21世纪,当今时代也有工业经济渐渐成了知识经济,信息经济的时代,信息的需求量的不听增加,促使了计算机通信的日新月异~虽然网络的使用频率与使用的范围都越来越广泛,但是人们使用的网络的用途主要还是只有两个:(1),相互之间的沟通,(2)资源共享。
局域网作为网络的一个重要组成部分,它不但是用户与外界连接的枢纽,同时也是近距离用户之间沟通与资源共享的一个重要途径。在这种情况下,如何使局域网内的用户便捷的沟通,以及快速的资源共享,也就成为了人们对网络研究的重点之一。 本系统模仿飞鸽传书,是一个局域网内的通讯工具,主要通过winsocket完成,它具有的功能有:
1)局域网内用户简单的文字聊天功能;
2)局域网内用户间相互的文件,文件夹传输。
在设计系统时,应根据简洁,流畅的特点安排布局,在编制程序时应充分考虑这一点,传输的稳定,快捷,真正做到“简洁,高效,流畅,安全”的使用环境。用户使用的过程为,显示用户登录开启本软件,软件制动检索局域网的其他用户,并以之成为用户列表,让用户选择。当用户发现所要连接的用户之后,双击该用户便可直接发送消息或者文件,接收方可以选择接受或者拒绝相应的传输文件 实验室管理系统方便了学校的教学设备进行统计及管理工作,减少每天需要涉及到的相关工作量,尽可能的提高工作效率,可以节省人力物力的浪费。本系统将会提高学校的办公效率和设备可靠性,减少工作人员的劳动强度,减少办公耗材,提高学校的现代化管理水平。
1.2技术分析
随着计算机和通讯技术的发展,计算机的网络化已经渗透到各个应用领域,尤其是以TCP、/IP协议之间的网络互连发展很快,计算机应用系统的开发由传统的单机方式转向到了网络环境的开发。
大部分编程语言都提供了基于WINDOW SOCKETS网络编程接口的WINSOCKET控件,他使开
1
飞鸽传书
发TCP/IP通讯变得简单方便。
网络之间进行数据通信时,试用地址来标识网络中的计算机,有了地址以后,数据才会准确的发送到地址所指向的计算机。TCP/IP协议使用IP地址为网络中计算机的标识,而且每台计算机的IP地址是唯一的,一般情况下,每台计算机运行的程序不止一个,因此要在应用程序中建立连接的话,还需要一个地址标识。
在TCP/IP协议书中使用端口(PORT)作为计算机上运行的应用程序的标识,因此在TCP/IP协议中一个有效的网络地址包括IP地址和端口地址两个部分。在TCP/IP协议提供了两种计算机之间的通讯方式:TCP方式和UDP方式。6
TCP是一种面向连接的服务,在文件传输时会先行建立连接,通过连接提供双向,有序且无重复的数据流服务,以及流量控制,差错检测和纠错等服务,从而确保文件传输的正确性;UDP则是一种无连接的服务,它在文件传输时不会确保传输端的文件能够正确无误的传送到接收端,所以当使用UDP时,通常要自己作接受确认的工作。
同时还启动线程Thread来控制整个运行过程,程序的运行效果我们不用运行也会知道,那就是在循环中将系统当前时间的毫秒部分输出出来,在每次输出之后会将当前线程暂停一下,直到10次之后运行完毕,终止线程的执行。线程的优点有以下: 1、缩短应用程序的响应时间。因为在线程池中有线程的线程处于等待分配任务状态(只要没有超过线程池的最大上限),无需创建线程。
2、不必管理和维护生存周期短暂的线程,不用在创建时为其分配资源,在其执行完任务之后释放资源。
3、线程池会根据当前系统特点对池内的线程进行优化处理。
总之使用线程池的作用就是减少创建和销毁线程的系统开销。在.NET中有一个线程的类ThreadPool,它提供了线程池的管理。
2
飞鸽传书
第2章 系统功能设计与实现
3.1系统目标设计
飞鸽传书系统首要实现的功能如下:
(1)实用性原则:真正为局域网的实际工作服务,按照需求的轻重缓急,合理涉及本系统。
(2)可靠性原则:必须为用户提供安全的服务,尤其要保证传输的稳定性。 (3)友好型原则:使用本系统的用户相当一部分对计算机知识了解很少,所以系统操作上要求简单方便,便于用户掌握。
(4)可扩展性原则:采用开放的标准和接口,便于系统向更大的规模和功能扩展。 3.2整体E-R图
E-R图分析的目的是确定系统中所有实体、及实体之间的联系。画E-R图通常使自底向上的设计,首先对局部视图进行分析设计,然后再将局部视图合并,消除冲突和冗余,得到 系统的总体E-R图。
3.2.2关系设计
第3章 实现
3.1上线提醒模块
上线提醒模块功能介绍:醒当前用户上线的好友,即时显示好友的昵称,IP在LISTBOX里
3
飞鸽传书
3.1.1界面
图3.1 飞鸽传书上线提醒界面界面
3.1.2代码
mySendData.commandNo = 0;
mySendData.commandNo1 = 0x01;
mySendData.fromIP = myIP;
mySendData.computerName = myName;
mySendData.toIP = myIP;
mySendData.content = "上线提示";
mySendData.texbig = 2;
; mySendData.texname = "12"
mySendData.texnamelength = 12;
mySendData.count = 13;
byte[] sendb = StructToBytes(mySendData);
SendPack(sendb);
mySendData.commandNo = 0;
mySendData.commandNo1 = 0x01;
mySendData.fromIP = myIP;
mySendData.computerName = myName;
mySendData.toIP = myIP;
mySendData.content = "上线提示";
mySendData.texbig = 2;
mySendData.texname = "12";
mySendData.texnamelength = 12;
mySendData.count = 13;
byte[] sendb = StructToBytes(mySendData);
SendPack(sendb);
if (recData.commandNo == 0x00)
{
(recData.toIP.Equals(myIP)) if
{
if (listBox1.FindString(recData.computerName + " " + recData.niname) <= 0)
{
sendDat sedata = new sendDat();
listBox1.Items.Add(recData.computerName + " " + recData.niname);
sedata.niname = name1;
sedata.fromIP = romeIP;
4
飞鸽传书
sedata.computerName = romeName;
send1.Add(sedata);
}
}
if (recData.fromIP.Equals(recData.toIP)) else
{
sendDat sedata = new sendDat();
//从其他机器发送过来的刷新请求
//返回自己的信息
mySendData.commandNo = 0x00;
mySendData.toIP = recData.toIP;
mySendData.content = "上线提示";
byte[] sendb = StructToBytes(mySendData);
SendPack(sendb);
//如果不存在则添加该用户
if (listBox1.FindString(recData.computerName + " " +
recData.niname) <= 0)
{
上线提示 f = new 上线提示();
textBox1.Text = recData.niname.ToString();
f.textBox1.Text = recData.niname.ToString();
f.Owner = this;
f.Show();
Thread.Sleep(2000);
listBox1.Items.Add(recData.computerName.ToString() + " " + recData.niname);
sedata.niname = name1;
sedata.fromIP = romeIP;
sedata.content = romeCon;
sedata.computerName = romeName;
send1.Add(sedata);
f.Close ();
button1_Click(null, null);
textBox1.Text = "";
}
}
if (recData.commandNo == 0x01)
{
5
飞鸽传书
listBox1.Items.Remove(recData.computerName + " " + recData.niname);
}
}
3.1.3实现过程
好友上线时,发送0和0x00命令以广播的形式发布在局域网中,把本机的IP主机号,电脑名以及昵称转化成比特流,通过端口号和IP地址组成的套接字传递过去,以及目的IP,昵称,以及电脑名把比特流转化成字节,与LISTBOX里的内容比较是否存在该电脑名和昵称,如果不存在则添加上。
3.2 文字聊天模块
文字聊天模块功能介绍:实现用户间的间交流
3.2.1界面
图3.2文字聊天界面
3.2.2代码
case 0x05://发言
{//当传送的不包含文件时才显示“有新消息了”
showNe();
}
6
飞鸽传书
break;
public void showNe()
{
//窗体显示
if (this.WindowState != FormWindowState.Normal)
{
.Visible = true; this
this.WindowState = FormWindowState.Normal;
}
newmsg.Text = "有新消息了";
newmsg.BringToFront();
private void button2_Click(object sender, EventArgs e)
{
if (listBox1.SelectedItems.Count == 0 || listBox1.SelectedIndex ==
0)
{
MessageBox.Show("请选择一个用户~~~");
return;
}
mySendData.commandNo = 0x05;
mySendData.fromIP = myIP;
mySendData.computerName = myName;
mySendData.texbig = 2;
mySendData.texname = "12";
mySendData.texnamelength = 12;
mySendData.count = 13;
mySendData.content =t_send.Text;
for (int i = 0; i < listBox1.Items.Count - 1; i++)
{
string[] str = Regex.Split(listBox1.SelectedItem.ToString(),
@"[ ]+");
if (send1[i].computerName == str[0].ToString())
{
mySendData.toIP = send1[i].fromIP;
}
}
byte[] sendb2 = StructToBytes(mySendData);
SendPack(sendb2);
t_send.Clear();
}
还可实现晴空功能其代码如下:
7
飞鸽传书
//清空
private void button3_Click(object sender, EventArgs e)
{
t_send.Text = string.Empty;
t_rec.Text = string.Empty;
}
3.2.3实现过程
选中对方主机名和昵称,从而获取对方的IP地址,向对方发送命令0x05,以及本地的电脑名,昵称,等一些内容,并把这些内容转化成比特流,发送给对方,当对方接收到0x05命令时会调用把比特流转化成字节,以消息的形式呈现在TEXTBOX里边
3.3传文件模块
传文件模块功能:实现对机房中运行状态为报废的设备的删除,以及对旧设备的报修、报废记录的删除。
3.3.1界面
3.3传文件模块界面
3.3.2代码
case 0x03://传文件
if (recData.toIP.Equals(myIP))
8
飞鸽传书
{//传送文件
Thread mysend = new Thread(new ThreadStart(sendFile));
mysend.Start();
}
break;
case 0x06://传文件
(recData.toIP.Equals(myIP)) if
{//传送文件
Thread mysen = new Thread(new ThreadStart(sendFil));
mysen.Start();
}
break;
case 0x02: //请求传文件
if (recData.toIP.Equals(myIP))
{//准备接收文件
romeFileName = romeCon.Split('+')[0];
romeFilel = romeCon.Split('+')[1];
readyRecFile();
}
break;
private void button4_Click(object sender, EventArgs e)
{
if (comboBox1.Text == "文件")
{
openFileDialog1.Filter = "所有文件|*.*|压缩文件|*.rar";
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
t_filep.Text = openFileDialog1.FileName;
}
}
//传文件
if (t_send.Text == ""&&comboBox1 .Text =="文件夹") // .Text != "")
{//需要传文件
//首先发送号命令要求对方准备接收
string[] sp = Regex.Split(strr12345 , @"[%]+");
for (int n = 1; n < tcountt+1; n++)
{
sendfilestream[n] = new FileStream(sp[n], FileMode.Open, FileAccess.Read);
}
long filelength = sendfilestream.Length;
string totalsteps;
9
飞鸽传书
int temp;
if (filelength / (1024 * 1024) > 10)
{//文件>10M时用M做为进度最小单位
temp = (int)(filelength / (1024 * 1024));
totalsteps = temp + "M";
}
else
{//小于M的文件用k做为最小单位
temp = (int)(filelength / 1024);
totalsteps = temp + "K";
}
//用做接收端时的公共变量保存发送的临时值
romeFilel = totalsteps;
string filename = Path.GetFileName(t_filep.Text);
mySendData.commandNo = 0x04;
mySendData.count = tcountt;
mySendData.content = str12 ;
mySendData.texname = strr12345;
mySendData.fromIP = myIP;
mySendData.computerName = myName;
for (int i = 0; i < listBox1.Items.Count - 1; i++)
{
string[] str = Regex.Split(listBox1.SelectedItem.ToString(),
@"[ ]+");
if (send1[i].computerName == str[0].ToString())
{
mySendData.toIP = send1[i].fromIP;
}
}
byte[] sendb = StructToBytes(mySendData);
SendPack(sendb);
t_send.Height = 120;
t_send.Top = 224;
comboBox1.Text = "";
if (t_send.Text == "")
{
return;
}
//界面上的处理
}
if (comboBox1 .Text == "文件" && t_filep.Text != "")
10
飞鸽传书
{//需要传文件
//首先发送号命令要求对方准备接收
sendfilestrea = new FileStream(t_filep.Text, FileMode.Open, FileAccess.Read);
long filelength = sendfilestrea.Length;
string totalsteps;
temp; int
if (filelength / (1024 * 1024) > 10)
{//文件>10M时用M做为进度最小单位
temp = (int)(filelength / (1024 * 1024));
totalsteps = temp + "M";
}
else
{//小于M的文件用k做为最小单位
temp = (int)(filelength / 1024);
totalsteps = temp + "K";
}
//用做接收端时的公共变量保存发送的临时值
romeFilel = totalsteps;
string filename = Path.GetFileName(t_filep.Text);
mySendData.commandNo = 0x02;
mySendData.fromIP = myIP;
mySendData.computerName = myName;
for (int i = 0; i < listBox1.Items.Count - 1; i++)
{
string[] str = Regex.Split(listBox1.SelectedItem.ToString(),
@"[ ]+");
if (send1[i].computerName == str[0].ToString())
{
mySendData.toIP = send1[i].fromIP;
}
}
mySendData.content = filename + "+" + totalsteps;//格式:
yy.txt+62K+64990
byte[] sendb = StructToBytes(mySendData);
SendPack(sendb); t_send.Height = 120;
t_send.Top = 224;
comboBox1 .Text = "";
if (t_send.Text == "")
{
return;
}
}
11
飞鸽传书
3.3.3实现过程
选中对方主机名和昵称,从而获取对方的IP地址,向对方发送命令0x02,并获取到文件名,即把文件内容转化成文件流,当对方接收到命令,开启文件监听线程。当点击接受时,返回一个0x04命令,当本地接收到一个命令后,启动文件发送线程并把文件流以1024比特转化成网络流发送给对方的监听线程,会监听到该端口号网络流,以1024比特转化成文件流,最终转化成文件及内容。
3.4昵称修改模块
昵称模块功能介绍:修改昵称使好友更加方便的找到,便于交流。 3.4.1界面
图3.4 昵称修改模块界面
3.4.2代码
private void Form1_Load(object sender, EventArgs e)
{
// myre.texbig = new long[100];
// myre.texname = new string[100];
End = new IPEndPoint(groupAddress, groupPort);
//和端口初始化计算机名
12
飞鸽传书
IPHostEntry myentry = Dns.GetHostByName(Dns.GetHostName());
myIP = new IPAddress(myentry.AddressList[0].Address);
myName = Dns.GetHostName();
listBox1.Items.Add("主机名 昵称");
//开启监听线程
runing = true;
myThread = new Thread(new ThreadStart(this.ListenPort)); Thread
myThread.IsBackground = true;
myThread.Start();
//发送上线信息
mySendData.niname = "";
{
FileStream fs1 = File.OpenRead(path);
StreamReader sr = new StreamReader(fs1);
while (sr.Peek() > -1)
mySendData.niname =sr.ReadLine();
sr.Close();
fs1.Close();
}
mySendData.commandNo = 0;
mySendData.commandNo1 = 0x01;
mySendData.fromIP = myIP;
mySendData.computerName = myName;
mySendData.toIP = myIP;
mySendData.content = "上线提示";
mySendData.texbig = 2;
mySendData.texname = "12";
mySendData.texnamelength = 12;
mySendData.count = 13;
byte[] sendb = StructToBytes(mySendData);
SendPack(sendb);
}
private void button1_Click(object sender, EventArgs e)
{
listBox1.Items.Clear();
listBox1.Items.Add("主机名 昵称");
mySendData.commandNo1 = 0x01;
mySendData.commandNo = 0x00;
mySendData.fromIP = myIP;
//mySendData.computerName = myName;
mySendData.niname = "";
{
13
飞鸽传书
FileStream fs1 = File.OpenRead(path);
StreamReader sr = new StreamReader(fs1);
while (sr.Peek() > -1)
mySendData.niname = sr.ReadLine();
sr.Close();
fs1.Close();
}
mySendData.toIP = myIP;
mySendData.content = "上线提示";
byte[] sendb = StructToBytes(mySendData);
SendPack(sendb);
}
private void 重命名ToolStripMenuItem_Click(object sender, EventArgs e)
{
if (File.Exists(path))
{
File.Delete(path);
}
FileStream fs = File.OpenWrite(path);
StreamWriter sw = new StreamWriter(fs);
sw.WriteLine(textBox1.Text);
sw.Close();
fs.Close();
button1_Click(null, null);
、
3.4.3实现过程
点击重命名时,发送0x00命令,以广播的形式,把新的昵称及本机地址IP转化成比特流,发送在局域网里,把新昵称转化成文件流,写入TXT里,当再次上线时,会以文件流的形式读出该昵称,从而达到本机的昵称修改,当局域网上的主机接收到广播时,在对方的主机上改变了自己的昵称。
3.5传文件夹模块
传文件夹模块功能介绍:现新设备的入库记录,旧设备的报修、报废记录的浏览。
14
飞鸽传书
3.5.1界面
图3.10传文件夹模块界面
3.5.2代码
private void button4_Click(object sender, EventArgs e)
{
if (comboBox1.Text == "文件")
{
openFileDialog1.Filter = "所有文件|*.*|压缩文件|*.rar";
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
t_filep.Text = openFileDialog1.FileName;
}
}
if (comboBox1.Text == "文件夹")
{
folderBrowserDialog1.ShowDialog();
t_filep.Text = folderBrowserDialog1.SelectedPath;
int f;
string[] filen;
string[] fil;
string filee;
string filea;
15
飞鸽传书
if (!Directory.Exists(t_filep.Text))
MessageBox.Show(textBox1.Text + "文件夹不存在", "信息提示", MessageBoxButtons.OK);
else
{
filen = Directory.GetFiles (t_filep.Text);
fil = Regex.Split(t_filep.Text, @"[\\]+");
filee =fil [fil .Length -1];
for ( f = 0; f <= filen.Length - 1; f++)
{
tigui(filen[f]);
filea = String.Format("{0}\t{1} {2}", filen[i], File.GetCreationTime(filen[i]), fileatt(filen[i]));
}
}
}
}
public void sendFile()
{
TcpClient serverClient = new TcpClient();
serverClient.Connect(romeIP , 2626);
NetworkStream stream = serverClient.GetStream();
//定义缓冲区
byte[] bb = new byte[1024];
//循环读文件
int number;
int stepoff;
if (romeFilel[romeFilel.Length - 1] == 'K')
stepoff = 1024;
else
stepoff = 1024 * 1024;
int totalste = int.Parse(romeFilel.Substring(0, romeFilel.Length - 1));
float sendedbytes = 0;
for (int n = 1; n < tcountt + 1; n++)
{
16
飞鸽传书
while ((number = sendfilestream[n].Read(bb, 0, 1024)) != 0)
{//向客户端发送流
stream.Write(bb, 0, number);
//刷新流
stream.Flush();
//进度条
}
sendfilestream[n].Close();
}
stream.Close();
MessageBox.Show("文件传送完毕~");
}
private void newmsg_Click(object sender, EventArgs e)
{
if (isfile=="wenjianjia")
{//当传送的含有文件时
saveFileDialog1.Filter = "所有格式|*.*";
saveFileDialog1.FileName = romeFileName;
saveFileDialog1.FileName = Regex.Split(strr123[1], @"[\\]+")[Regex.Split(strr123[1], @"[\\]+").Length - 2];
if (saveFileDialog1.ShowDialog() == DialogResult.OK)
{
Directory.CreateDirectory(saveFileDialog1.FileName.ToString());
}
else
return;
t_rec.Text = "消息来自" + romeName + "(" + romeIP.ToString() + ")" + DateTime.Now.ToShortDateString();
t_rec.Text += "\r\n> " + romeCon;
//界面的处理
newmsg.SendToBack();
t_send.Height = 120;
t_send.Top = 224;
//返回一个确认接收包
mySendData.commandNo = 0x03;
mySendData.fromIP = myIP;
mySendData.computerName = myName;
mySendData.toIP = romeIP;
mySendData.content = "ready!";
byte[] sendb = StructToBytes(mySendData);
SendPack(sendb);
//复位文件标志
isfile = "";
17
飞鸽传书
//同时开启线程开始监听
Thread myrecv = new Thread(new ThreadStart(listenPort));
myrecv.Start();
return;
}
else if (isfile=="wenjian")
{//当传送的含有文件时
saveFileDialog1.Filter = "所有格式|*.*";
saveFileDialog1.FileName = romeFileName;
if (saveFileDialog1.ShowDialog() == DialogResult.OK)
savePath = saveFileDialog1.FileName;
else
return;
t_rec.Text = "消息来自" + romeName + "(" + romeIP.ToString() + ")" + DateTime.Now.ToShortDateString();
t_rec.Text += "\r\n> " + romeCon;
//界面的处理
newmsg.SendToBack();
t_send.Height = 120;
t_send.Top = 224;
//返回一个确认接收包
mySendData.commandNo = 0x06;
mySendData.fromIP = myIP;
mySendData.computerName = myName;
mySendData.toIP = romeIP;
mySendData.content = "ready!";
byte[] sendb = StructToBytes(mySendData);
SendPack(sendb);
//复位文件标志
isfile = "";
//同时开启线程开始监听
Thread myrecv = new Thread(new ThreadStart(listenPor));
myrecv.Start();
return;
}
t_rec.Text = "消息来自" + romeName + "(" + romeIP.ToString() + ")" + DateTime.Now.ToShortDateString();
t_rec.Text += "\r\n> " + romeCon;
mySendData.commandNo = 0x09;
mySendData.toIP = romeIP;
mySendData.content = "信息被打开~";
byte[] sendb2 = StructToBytes(mySendData);
SendPack(sendb2);
18
飞鸽传书
newmsg.SendToBack();
}
3.5.3实现过程
选中对方主机名和昵称,从而获取对方的IP地址,向对方发送命令0x04,并获取到文件夹下的所有文件名,以%为间隔符连接在一块,然后把每个文件内容转化成文件流数组,把文件个数,每个文件的大小,以及文件的名字发送给对方,当对方接收到命令,开启文件夹监听线程。当点击接受时,返回一个0x03命令,当本地接收到一个命令后,启动文件夹发送线程并把数组文件流以1024比特转化成网络流发送给对方的监听线程,会监听到该端口号网络流,以1比特的形式转化成文件流,当转化的比特与该文件的大小相等时,结束本文件的写入,进入下一文件的内容转换,最终把所有文件转化成文件及内容。
19
飞鸽传书
第4章 结束语
在编程过程中我认识到了: 虽然我们做的实验室设备系统最终完成了,达到了课题的要求,但却存在着许多的不足,保密工作,文件,文件夹的传输拒绝方面,聊天记录的保存,代码部分有很大的不足, 语句过于繁琐,没有突出程序的简易性, 并且,我们在在界面上未改变。还有就是,开始时界面过多,通过不断的改善才是系统变得简单易操作,这些问题最终导致了我们所做的实验室设备管理系统没有充分的体现出它应有的优越性,如查找方便,可靠性高,存储量大,保密性好,寿命长,成本低,管理自动化的需求
在做课题的过程中,我们遇到了重重的困难,这时才发现自己的知识是那么的匮乏,只是面试那么的狭隘,并且还缺少一定的实践能力。但是通过查阅资料,一点一点的从头学起,请教老师和同学,进行讨论,自我摸索,一次次的修改,调试,一次次的重新来过,最终功夫不负有心人所有的问题都解决,课题最终顺利通过
为了顺利通过课题,我们尽可能多地运用所学知识点,灵活完成编码通过问题分析和任务定义,做课题锻炼了我们的分析问题的能力;通过逻辑设计体现我们的抽象能力;通过详细设计和程序编码体现我们解决问题的能力;通过程序调试与测试体现我们动手能力;通过结果分析体现我们认识问题的能力;通过编写课题设计报告体现我们书写程序文档的能力。
感悟:
平时的学习,我觉得有必要调整一下,如果能像做课题那样高度集中精力,运用各种方法,上网查询,请教老师,请教同学,不断的完善自己的知识,拓展自己的知识面,熟练地掌握程序设计方法和思想, 认真的做好每个细节,有方向有目的去培养自己的程序设计能力和软件工程能力,发挥自己的创造力来分析问题、解决问题。我相信在四年里,我可以学到很多,走得更远。一分耕耘,一分收获。我会走向成功。最后感谢老师的指导和帮助,让我们能够顺利的完成这次任务。
20
飞鸽传书
参考文献
[1]马煜,陈海军,朱朝阳,Visual C#.NET案例开发锦集,电子工业出版社, 2008.4 [2]李春葆、谭成予、金晶、曾平,C#程序设计教程,北京:清华大学出版社,2010.1
21
飞鸽传书
指导教师评语
成绩:
指导教师签名:
年 月 日
22
飞鸽传书
附录B: 主要源程序
namespace pro123
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = false;
}
string path = "MyTest.txt";
public bool runing = false; //标志
public UdpClient listen = new UdpClient(2525);
public IPEndPoint End;
public IPAddress groupAddress = IPAddress.Parse("255.255.255.255"); //广播地址
public int groupPort = 2525; //广播端口
public IPAddress myIP;
public string myName;
public sendData mySendData = new sendData(); //本地的号命令发送包
public string romeName;
public IPAddress romeIP;
public string romeCon;
public string isfile;//传送文件标志
public string savePath;//传文件的保存地址
public string romeFileName;//远程文件名
public string romeFilel;//远程文件用单位表示的长度,格式为43M或K
public FileStream []sendfilestream=new FileStream [100];
public FileStream sendfilestrea ;
//发送文件流
public struct sendData
{
public byte commandNo1;
public byte commandNo;//命令号1字节
public IPAddress fromIP;//发送端IP 4字节
public int nameLength; //名字的字节数 4字节
public string computerName;//计算机名 x字节
public IPAddress toIP;//接收端IP;4字节
public string content;//内容 y字节
23
飞鸽传书
public int ninamelength;
public long texbig ;
public int count;
string texname; public
public int texnamelength;
public string niname;
};
List
send1 = new List();
private void Form1_Load(object sender, EventArgs e)
{
// myre.texbig = new long[100];
// myre.texname = new string[100];
End = new IPEndPoint(groupAddress, groupPort);
//和端口初始化计算机名
IPHostEntry myentry = Dns.GetHostByName(Dns.GetHostName());
myIP = new IPAddress(myentry.AddressList[0].Address);
myName = Dns.GetHostName();
listBox1.Items.Add("主机名 昵称");
//开启监听线程
runing = true;
Thread myThread = new Thread(new ThreadStart(this.ListenPort));
myThread.IsBackground = true;
myThread.Start();
//发送上线信息
mySendData.niname = "";
{
FileStream fs1 = File.OpenRead(path);
StreamReader sr = new StreamReader(fs1);
while (sr.Peek() > -1)
mySendData.niname =sr.ReadLine();
sr.Close();
fs1.Close();
}
mySendData.commandNo = 0;
mySendData.commandNo1 = 0x01;
mySendData.fromIP = myIP;
mySendData.computerName = myName;
mySendData.toIP = myIP;
mySendData.content = "上线提示";
mySendData.texbig = 2;
mySendData.texname = "12";
mySendData.texnamelength = 12;
24
飞鸽传书
mySendData.count = 13;
byte[] sendb = StructToBytes(mySendData);
SendPack(sendb);
}
public void ListenPort()
{
//listBox1.Items.Clear();
send1.Clear();
IPEndPoint tempEnd = new IPEndPoint(IPAddress.Any, 2525);
while (runing)
{
Application.DoEvents();
if (this.IsDisposed) break;
try
{
byte[] recb = listen.Receive(ref tempEnd);
// 检查所接收到的信息and处理之
checkMessage(recb);
}
catch (Exception e)
{
MessageBox.Show("出现错误:" + e.Message.ToString());
break;
}
}
listen.Close();
listBox1.Items.Add("线程已经退出~");
runing = false;
}
public void SendPack(byte[] sendbs)
{
//listBox1.Items.Clear();
try
{
listen.Send(sendbs, sendbs.Length, End);
}
catch (Exception e)
{
25
飞鸽传书
MessageBox.Show(e.Message.ToString());
}
}
int tcount = 0; static
int fl = 0, fy = 0;
public long[] ap = new long[100];
public long[] aq = new long[100];
public static byte[] StructToBytes(sendData structObj)
{
byte[] commandb1 = new byte[1];
commandb1[0] = structObj.commandNo1;
byte[] commandb = new byte[1];
commandb[0] = structObj.commandNo;
byte[] fromipb = structObj.fromIP.GetAddressBytes();
byte[] nameb = Encoding.Default.GetBytes(structObj.computerName);
byte[] lengthb = BitConverter.GetBytes(nameb.Length);
byte[] toipb = structObj.toIP.GetAddressBytes();
byte[] contentb = Encoding.Default.GetBytes(structObj.content);
byte[] ninamea = Encoding.Default.GetBytes(structObj .niname );
byte[] nilegth = BitConverter.GetBytes(ninamea.Length);
byte []textname=Encoding .Default .GetBytes (structObj .texname );
byte[] textnamelength = BitConverter.GetBytes(textname.Length);
byte[] textbig = BitConverter.GetBytes(structObj.texbig);
byte[] textcount = BitConverter.GetBytes(structObj.count);
byte[] buffer = new byte[14+ nameb.Length +
contentb.Length+ninamea .Length+20+textname .Length ];
int index = 0;
commandb1.CopyTo(buffer, index);
index += commandb1.Length;
commandb.CopyTo(buffer, index);
index += commandb.Length;
fromipb.CopyTo(buffer, index);
index += fromipb.Length;
lengthb.CopyTo(buffer, index);
index += lengthb.Length;
nameb.CopyTo(buffer, index);
index += nameb.Length;
nilegth.CopyTo(buffer, index);
index += nilegth.Length;
ninamea.CopyTo(buffer, index);
index += ninamea.Length;
toipb.CopyTo(buffer, index);
26
飞鸽传书
index += toipb.Length;
textnamelength.CopyTo(buffer, index);
index += textnamelength.Length;
textname.CopyTo(buffer, index);
index += textname.Length;
textbig.CopyTo(buffer, index);
index += textbig.Length;
textcount.CopyTo(buffer, index);
index += textcount.Length;
contentb.CopyTo(buffer, index);
return buffer;
}
//public sendDat sedata=new sendDat () ;
public string name1;
string[] strr12;
string[] strr123;
int coun = 0;
public void checkMessage(byte[] recbb)
{
//listBox1.Items.Clear();
sendData recData = BytesToStruct(recbb);
if (recData.commandNo == 0x04)
{
fl = 1;
strr12 = Regex.Split(recData.content, @"[%]+");
strr123 = Regex.Split(recData.texname, @"[%]+");
coun = recData.count;
romeName = recData.computerName;
romeIP = recData.fromIP;
romeCon = recData.content;
name1 = recData.niname;
}
else if (recData.commandNo == 0x02)
{
fy = 1;
romeName = recData.computerName;
romeIP = recData.fromIP;
romeCon = recData.content;
name1 = recData.niname;
}
else
{
27
飞鸽传书
romeName = recData.computerName;
romeIP = recData.fromIP;
romeCon = recData.content;
name1 = recData.niname;
}
if (recData.commandNo == 0x00)
{
if (recData.toIP.Equals(myIP))
{
if (listBox1.FindString(recData.computerName + " " + recData.niname) <= 0)
{
sendDat sedata = new sendDat();
listBox1.Items.Add(recData.computerName + " " + recData.niname);
sedata.niname = name1;
sedata.fromIP = romeIP;
sedata.computerName = romeName;
send1.Add(sedata);
}
}
else if (recData.fromIP.Equals(recData.toIP))
{
sendDat sedata = new sendDat();
//从其他机器发送过来的刷新请求
//返回自己的信息
mySendData.commandNo = 0x00;
mySendData.toIP = recData.toIP;
mySendData.content = "上线提示";
byte[] sendb = StructToBytes(mySendData);
SendPack(sendb);
//如果不存在则添加该用户
if (listBox1.FindString(recData.computerName + " " + recData.niname) <= 0)
{
上线提示 f = new 上线提示();
textBox1.Text = recData.niname.ToString();
f.textBox1.Text = recData.niname.ToString();
f.Owner = this;
f.Show();
Thread.Sleep(2000);
28
飞鸽传书
listBox1.Items.Add(recData.computerName.ToString() + " " + recData.niname);
sedata.niname = name1;
sedata.fromIP = romeIP;
sedata.content = romeCon;
sedata.computerName = romeName;
send1.Add(sedata);
f.Close ();
button1_Click(null, null);
textBox1.Text = "";
}
}
if (recData.commandNo == 0x01)
{
listBox1.Items.Remove(recData.computerName + " " + recData.niname);
}
}
switch (recData.commandNo)
{
case 0x05://发言
{//当传送的不包含文件时才显示“有新消息了”
showNe();
}
break;
case 0x04: //请求传文件
if (recData.toIP.Equals(myIP))
{//准备接收文件
readyRecFile();
}
break;
case 0x03://传文件
if (recData.toIP.Equals(myIP))
{//传送文件
Thread mysend = new Thread(new ThreadStart(sendFile));
mysend.Start();
}
break;
case 0x06://传文件
if (recData.toIP.Equals(myIP))
{//传送文件
Thread mysen = new Thread(new ThreadStart(sendFil));
mysen.Start();
29
飞鸽传书
}
break;
case 0x07:
{
(listBox1.FindString(recData.computerName + " " + recData.niname) >= 0) if
{
listBox1.Items.Remove(recData.computerName.ToString() + " " + recData.niname);
}
if (listBox1.FindString(recData.computerName + " " + recData.content ) <= 0)
{
listBox1.Items.Add(recData.computerName.ToString() + " " + recData.content );
}
}
break;
case 0x02: //请求传文件
if (recData.toIP.Equals(myIP))
{//准备接收文件
romeFileName = romeCon.Split('+')[0];
romeFilel = romeCon.Split('+')[1];
readyRecFile();
}
break;
case 0x08://用户离线
if (listBox1.FindString(recData.computerName + " " + recData.niname) >= 0)
{
if (recData.computerName.ToString () == myName && recData.niname ==name1 )
{
Form f=new Form1() ;
f.Close ();
}
else
listBox1.Items.Remove (recData.computerName.ToString() + " " + recData.niname);
}
break;
case 0x09: //确认包
30
飞鸽传书
if (recData.toIP.Equals(myIP))
MessageBox.Show("信息来自:" + recData.computerName + "(" +
recData.fromIP.ToString() + ")\r\n" + recData.content, "消息");
break;
}
}
int texcount = 0;
public static sendData BytesToStruct(byte[] bytes)
{
sendData myre = new sendData();
myre.commandNo1 = bytes[0];
myre.commandNo = bytes[1];
byte[] ipb = new byte[4];
Array.Copy(bytes, 2, ipb, 0, 4);
myre.fromIP = IPAddress.Parse(ipByteToString(ipb));
myre.nameLength = BitConverter.ToInt32(bytes, 6);
myre.computerName = Encoding.Default.GetString(bytes, 10, myre.nameLength);
myre.ninamelength = BitConverter.ToInt32(bytes,10+myre .nameLength );
myre.niname = Encoding.Default.GetString(bytes, 14 + myre.nameLength , myre.ninamelength);
Array.Copy(bytes, 14 + myre.nameLength+myre.ninamelength , ipb, 0, 4);
myre.toIP = IPAddress.Parse(ipByteToString(ipb));
myre.texnamelength = BitConverter.ToInt32(bytes, 18 + myre.nameLength + myre.ninamelength);
myre.texname = Encoding.Default.GetString(bytes, 22 + myre.nameLength + myre.ninamelength, myre.texnamelength );
myre .texbig =BitConverter .ToInt32 (bytes ,22 + myre.nameLength + myre.ninamelength+myre .texnamelength );
myre.count = BitConverter.ToInt32(bytes, 30 + myre.nameLength + myre.ninamelength + myre.texnamelength);
myre.content = Encoding.Default.GetString(bytes, 34 + myre.nameLength + myre.ninamelength +
myre.texnamelength, bytes.Length - 34 - myre.nameLength - myre.ninamelength - myre.texnamelength);
return myre;
}
public static string ipByteToString(byte[] ipbt)
{
string temp = "";
temp = (int)ipbt[0] + "." + (int)ipbt[1] + "." + (int)ipbt[2] + "." + (int)ipbt[3];
return temp;
}
private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
{
if (listBox1.SelectedItems.Count != 0)
31
飞鸽传书
{
listBox1.ContextMenuStrip = contextMenuStrip1;
}
}
private void 重命名ToolStripMenuItem_Click(object sender, EventArgs e)
{
if (File.Exists(path))
{
File.Delete(path);
}
FileStream fs = File.OpenWrite(path);
StreamWriter sw = new StreamWriter(fs);
sw.WriteLine(textBox1.Text);
sw.Close();
fs.Close();
button1_Click(null, null);
}
private void button1_Click(object sender, EventArgs e)
{
listBox1.Items.Clear();
listBox1.Items.Add("主机名 昵称");
mySendData.commandNo1 = 0x01;
mySendData.commandNo = 0x00;
mySendData.fromIP = myIP;
mySendData.niname = "";
{
FileStream fs1 = File.OpenRead(path);
StreamReader sr = new StreamReader(fs1);
while (sr.Peek() > -1)
mySendData.niname = sr.ReadLine();
sr.Close();
fs1.Close();
}
mySendData.toIP = myIP;
mySendData.content = "上线提示";
byte[] sendb = StructToBytes(mySendData);
SendPack(sendb);
}
//清空
private void button3_Click(object sender, EventArgs e)
{
32
飞鸽传书
t_send.Text = string.Empty;
t_rec.Text = string.Empty;
}
//发送消息
void button2_Click(object sender, EventArgs e) private
{
if (listBox1.SelectedItems.Count == 0 || listBox1.SelectedIndex == 0)
{
MessageBox.Show("请选择一个用户~~~");
return;
}
//传文件
if (t_send.Text == ""&&comboBox1 .Text =="文件夹") // .Text != "")
{//需要传文件
//首先发送号命令要求对方准备接收
string[] sp = Regex.Split(strr12345 , @"[%]+");
for (int n = 1; n < tcountt+1; n++)
{
sendfilestream[n] = new FileStream(sp[n], FileMode.Open, FileAccess.Read);
}
long filelength = sendfilestream.Length;
string totalsteps;
int temp;
if (filelength / (1024 * 1024) > 10)
{//文件>10M时用M做为进度最小单位
temp = (int)(filelength / (1024 * 1024));
totalsteps = temp + "M";
}
else
{//小于M的文件用k做为最小单位
temp = (int)(filelength / 1024);
totalsteps = temp + "K";
}
//用做接收端时的公共变量保存发送的临时值
romeFilel = totalsteps;
string filename = Path.GetFileName(t_filep.Text);
mySendData.commandNo = 0x04;
mySendData.count = tcountt;
mySendData.content = str12 ;
mySendData.texname = strr12345;
mySendData.fromIP = myIP;
mySendData.computerName = myName;
for (int i = 0; i < listBox1.Items.Count - 1; i++)
33
飞鸽传书
{
string[] str = Regex.Split(listBox1.SelectedItem.ToString(), @"[ ]+");
if (send1[i].computerName == str[0].ToString())
{
mySendData.toIP = send1[i].fromIP;
}
}
byte[] sendb = StructToBytes(mySendData);
SendPack(sendb);
t_send.Height = 120;
t_send.Top = 224;
comboBox1.Text = "";
if (t_send.Text == "")
{
return;
}
//界面上的处理
}
(comboBox1 .Text == "文件" && t_filep.Text != "") if
{//需要传文件
//首先发送号命令要求对方准备接收
sendfilestrea = new FileStream(t_filep.Text, FileMode.Open, FileAccess.Read);
long filelength = sendfilestrea.Length;
string totalsteps;
int temp;
if (filelength / (1024 * 1024) > 10)
{//文件>10M时用M做为进度最小单位
temp = (int)(filelength / (1024 * 1024));
totalsteps = temp + "M";
}
else
{//小于M的文件用k做为最小单位
temp = (int)(filelength / 1024);
totalsteps = temp + "K";
}
//用做接收端时的公共变量保存发送的临时值
romeFilel = totalsteps;
string filename = Path.GetFileName(t_filep.Text);
mySendData.commandNo = 0x02;
mySendData.fromIP = myIP;
mySendData.computerName = myName;
34
飞鸽传书
for (int i = 0; i < listBox1.Items.Count - 1; i++)
{
string[] str = Regex.Split(listBox1.SelectedItem.ToString(), @"[ ]+");
if (send1[i].computerName == str[0].ToString())
{
mySendData.toIP = send1[i].fromIP;
}
}
mySendData.content = filename + "+" + totalsteps;//格式:yy.txt+62K+64990
byte[] sendb = StructToBytes(mySendData);
SendPack(sendb); t_send.Height = 120;
t_send.Top = 224;
comboBox1 .Text = "";
if (t_send.Text == "")
{
return;
}
}
mySendData.commandNo = 0x05;
mySendData.fromIP = myIP;
mySendData.computerName = myName;
mySendData.texbig = 2;
mySendData.texname = "12";
mySendData.texnamelength = 12;
mySendData.count = 13;
mySendData.content =t_send.Text;
for (int i = 0; i < listBox1.Items.Count - 1; i++)
{
string[] str = Regex.Split(listBox1.SelectedItem.ToString(), @"[ ]+");
if (send1[i].computerName == str[0].ToString())
{
mySendData.toIP = send1[i].fromIP;
}
}
byte[] sendb2 = StructToBytes(mySendData);
SendPack(sendb2);
t_send.Clear();
}
public void showNe()
{
//窗体显示
if (this.WindowState != FormWindowState.Normal)
35
飞鸽传书
{
this.Visible = true;
this.WindowState = FormWindowState.Normal;
}
有新消息了"; newmsg.Text = "
newmsg.BringToFront();
}
//准备接收文件
public void readyRecFile()
{
t_rec.BackColor = Color.Blue;
if (fl == 1)
{
fl = 0;
isfile = "wenjianjia";
}
else if (fy == 1)
{
isfile ="wenjian";
}
newmsg.Text = romeFileName + "(" + romeFilel + ")";
newmsg.BringToFront();
}
//单击显示接收的信息并隐藏自身
private void newmsg_Click(object sender, EventArgs e)
{
if (isfile=="wenjianjia")
{//当传送的含有文件时
saveFileDialog1.Filter = "所有格式|*.*";
saveFileDialog1.FileName = romeFileName;
saveFileDialog1.FileName = Regex.Split(strr123[1], @"[\\]+")[Regex.Split(strr123[1],
@"[\\]+").Length - 2];
if (saveFileDialog1.ShowDialog() == DialogResult.OK)
{
Directory.CreateDirectory(saveFileDialog1.FileName.ToString());
}
else
return;
t_rec.Text = "消息来自" + romeName + "(" + romeIP.ToString() + ")" +
DateTime.Now.ToShortDateString();
t_rec.Text += "\r\n> " + romeCon;
//界面的处理
36
飞鸽传书
newmsg.SendToBack();
t_send.Height = 120;
t_send.Top = 224;
//返回一个确认接收包
mySendData.commandNo = 0x03;
mySendData.fromIP = myIP;
mySendData.computerName = myName;
mySendData.toIP = romeIP;
mySendData.content = "ready!";
byte[] sendb = StructToBytes(mySendData);
SendPack(sendb);
//复位文件标志
isfile = "";
//同时开启线程开始监听
Thread myrecv = new Thread(new ThreadStart(listenPort));
myrecv.Start();
return;
}
else if (isfile=="wenjian")
{//当传送的含有文件时
saveFileDialog1.Filter = "所有格式|*.*";
saveFileDialog1.FileName = romeFileName;
if (saveFileDialog1.ShowDialog() == DialogResult.OK)
savePath = saveFileDialog1.FileName;
else
return;
t_rec.Text = "消息来自" + romeName + "(" + romeIP.ToString() + ")" + DateTime.Now.ToShortDateString();
t_rec.Text += "\r\n> " + romeCon;
//界面的处理
newmsg.SendToBack();
t_send.Height = 120;
t_send.Top = 224;
//返回一个确认接收包
mySendData.commandNo = 0x06;
mySendData.fromIP = myIP;
mySendData.computerName = myName;
mySendData.toIP = romeIP;
mySendData.content = "ready!";
byte[] sendb = StructToBytes(mySendData);
SendPack(sendb);
//复位文件标志
isfile = "";
37
飞鸽传书
//同时开启线程开始监听
Thread myrecv = new Thread(new ThreadStart(listenPor));
myrecv.Start();
return;
}
t_rec.Text = "消息来自" + romeName + "(" + romeIP.ToString() + ")" + DateTime.Now.ToShortDateString();
t_rec.Text += "\r\n> " + romeCon;
mySendData.commandNo = 0x09;
mySendData.toIP = romeIP;
mySendData.content = "信息被打开~";
byte[] sendb2 = StructToBytes(mySendData);
SendPack(sendb2);
newmsg.SendToBack();
}
q; string
string p;
TcpListener listenern = new TcpListener(2626);
public void listenPort()
{
b = 1;
if (a == 0)
{
listenern.Start();
}
Socket s = listenern.AcceptSocket();
for (int n = 1; n < coun+1; n++)
{
ap[n] = Convert.ToInt32(strr12[n]);
q = Regex.Split(strr123[n], @"[\\]+")[Regex.Split(strr123[n], @"[\\]+").Length - 2] +"\\"+
Regex.Split(strr123[n], @"[\\]+")[Regex.Split(strr123[n], @"[\\]+").Length - 1];
FileStream filestream = new FileStream(q, FileMode.OpenOrCreate, FileAccess.Write);
NetworkStream stream = new NetworkStream(s);
//定义缓冲区
byte[] bb = new byte[1];
//循环读socket流
tt = 0; int
//进度条
int stepoff=0;
float recbytes = 0;
while (stepoff != ap[n])
38
飞鸽传书
{//接收数据
stepoff++;
tt = stream.Read(bb, 0, 1);
filestream.Write(bb, 0, tt);
filestream.Flush();
//更新进度条
}
filestream.Close();
}
MessageBox.Show("文件接收完毕~");
}
int a = 0, b = 0;
public void listenPor()
{
a = 1;
if (b == 0)
{
listenern.Start();
}
Socket s = listenern.AcceptSocket();
FileStream filestrea = new FileStream(savePath, FileMode.OpenOrCreate, FileAccess.Write);
NetworkStream stream = new NetworkStream(s);
//定义缓冲区
byte[] bb = new byte[1024];
//循环读socket流
int tt = 0;
//进度条
int stepoff;
if (romeFilel[romeFilel.Length - 1] == 'K')
stepoff = 1024;
else
stepoff = 1024 * 1024;
int totalste = int.Parse(romeFilel.Substring(0, romeFilel.Length - 1));
float recbytes = 0;
while ((tt = stream.Read(bb, 0, 1024)) != 0)
{//接收数据
filestrea.Write(bb, 0, tt);
filestrea.Flush();
//更新进度条
}
filestrea.Close();
MessageBox.Show("文件接收完毕~");
}
39
飞鸽传书
public IPAddress groupAddres = IPAddress.Parse("169.254.92.136");
public void sendFile()
{
TcpClient serverClient = new TcpClient();
serverClient.Connect(romeIP , 2626);
NetworkStream stream = serverClient.GetStream();
//定义缓冲区
byte[] bb = new byte[1024];
//循环读文件
int number;
//进度条
int stepoff;
if (romeFilel[romeFilel.Length - 1] == 'K')
stepoff = 1024;
else
stepoff = 1024 * 1024;
int totalste = int.Parse(romeFilel.Substring(0, romeFilel.Length - 1));
float sendedbytes = 0;
for (int n = 1; n < tcountt + 1; n++)
{
while ((number = sendfilestream[n].Read(bb, 0, 1024)) != 0)
{//向客户端发送流
stream.Write(bb, 0, number);
//刷新流
stream.Flush();
//进度条
}
sendfilestream[n].Close();
}
stream.Close();
MessageBox.Show("文件传送完毕~");
}
public void sendFil()
{
TcpClient serverClient = new TcpClient();
serverClient.Connect(romeIP , 2626);
NetworkStream stream = serverClient.GetStream();
//定义缓冲区
byte[] bb = new byte[1024];
//循环读文件
int number;
//进度条
40
飞鸽传书
int stepoff;
if (romeFilel[romeFilel.Length - 1] == 'K')
stepoff = 1024;
else
stepoff = 1024 * 1024;
int totalste = int.Parse(romeFilel.Substring(0, romeFilel.Length - 1));
float sendedbytes = 0;
while ((number = sendfilestrea.Read(bb, 0, 1024)) != 0)
{//向客户端发送流
stream.Write(bb, 0, number);
//刷新流
stream.Flush();
//进度条
}
sendfilestrea.Close();
stream.Close()
MessageBox.Show("文件传送完毕~");
}
private void button4_Click(object sender, EventArgs e)
{
(comboBox1.Text == "文件") if
{
openFileDialog1.Filter = "所有文件|*.*|压缩文件|*.rar";
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
t_filep.Text = openFileDialog1.FileName;
}
}
if (comboBox1.Text == "文件夹")
{
folderBrowserDialog1.ShowDialog();
t_filep.Text = folderBrowserDialog1.SelectedPath;
int f;
string[] filen;
string[] fil;
string filee;
string filea;
if (!Directory.Exists(t_filep.Text))
MessageBox.Show(textBox1.Text + "文件夹不存在", "信息提示", MessageBoxButtons.OK);
else
{
filen = Directory.GetFiles (t_filep.Text);
41
飞鸽传书
fil = Regex.Split(t_filep.Text, @"[\\]+");
filee =fil [fil .Length -1];
for ( f = 0; f <= filen.Length - 1; f++)
{
tigui(filen[f]);
filea = String.Format("{0}\t{1} {2}", filen[i], File.GetCreationTime(filen[i]),
fileatt(filen[i]));
}
}
}
}
private void Form1_FormClosed(object sender, FormClosedEventArgs e)
{
runing = false;
mySendData.commandNo = 0x08;
mySendData.fromIP = myIP;
mySendData.computerName = myName;
mySendData.toIP = myIP;
{
string[] str = Regex.Split(listBox1.Items[1].ToString(), @"[ ]+");
{
mySendData.niname = str[1].ToString();
}
}
mySendData.content = "离线提示";
byte[] sendb = StructToBytes(mySendData);
SendPack(sendb);
}
int i = 0;
string str2;
string str4 = "";
int cccount = 0;
public string tigui(string str1)
{
if (Directory.Exists(str1) && !File.Exists(str1))
{
}
else
{
str2 = str1;
42
飞鸽传书
}
if (Directory.Exists(str1) && !File.Exists(str1))
{
for (int k = 0; k < Directory.GetFileSystemEntries(str1).Length; k++)
{
str2 = Directory.GetFileSystemEntries(str1)[k];
if (File.Exists(str1) && !Directory.Exists(str1))
{
}
else
{
str4 = str1;
}
tigui(str2);
}
}//就是文件夹。
else
{
tcountt++;
FileInfo fi = new FileInfo(str2);
str12=str12 +"%"+ fi .Length .ToString ();
strr12345 = strr12345 +"%"+ str2;
}
return str1;
}
int tcountt = 0;
string str12, str123,strr1234,strr12345;
private string fileatt(string filename) //获取文件属性
{
string fa = "";
switch (File.GetAttributes(filename))
{
case FileAttributes.Archive:
fa = "存档";
break;
case FileAttributes.ReadOnly:
fa = "只读";
break;
case FileAttributes.Hidden:
fa = "隐藏";
break;
43
飞鸽传书
case FileAttributes.Archive | FileAttributes.ReadOnly:
fa = "存档+只读";
break;
case FileAttributes.Archive | FileAttributes.Hidden:
fa = "存档+隐藏";
break;
case FileAttributes.ReadOnly | FileAttributes.Hidden:
fa = "只读+隐藏";
break;
case FileAttributes.Archive | FileAttributes.ReadOnly | FileAttributes.Hidden:
fa = "存档+只读+隐藏";
break;
}
return fa;
}
}
}
44