-
《高级网络程序设计》
课程设计报告
题
目
基于<
/p>
TCP
的局域网即时消息系统
的客户端和服务器端的设计与实现
学
号
姓
名
计算机网络工程教研室
2016
p>
年
01
月
11
日
目
录
一、课程设计内容
……………………
…………………
..2
二、设计目的
……………………………………………
..2
三、设计步骤
……………………………………………
..2
四、具体要求
………………………………………….....
3
五、实验代码
…………………………
…………………
. 3
六、
实验结果
……………………………………<
/p>
..
……
20
七、
参考
文献
……………………………………
..
……
22
< br>八、
实验心得
……………………………………
..
……
22
I
天津科技大学计算机学院
《高级网络程序设计》
课程设计
一、课程设计内容
1
.
Winsock
的启动与终止。
2
.
Winsock
的创建及绑定和关闭。
3
.
建立通
信连接
listen
及
accept<
/p>
和
connect
。
4
.
数据的传输。
5
.
简单的
客户机
/
服务器之间的通信。
二、设计目的
1
.
熟悉
Windows Socket
的
常用函数的形式和使用方法,理解数据通信的过程。
2
.
掌握如
何利用
C#
进行
TCP
协议开发,完成基于
TCP
的局域网即时消息系统的客
户端和服务器端的设计与实现。
三、设计步骤
在
TCP
/IP
网络中两个进程间的相互作用的主机模式是客户机
/
p>
服务器模式
(Client/Server model)
。该模式的建立基于以下两点:
(
1
)非对等作用;
(
2
)通
信完全是异步
的。客户机
/
服务器模式
在操作过程中采取的是主动请示方式:
1
、首先服务器方要先启动,并根据请示提供相应服务,其过程如下:
(
1
)打开一通信通道并告知本地主机,它愿意在某
一个公认地址上接收客户请求。
(
2
)等待客户请求到达该端口。
(
p>
3
)接收到重复服务请求,处理该请求并发送应答信号。
(
4
)返回第二步,等
待另一客户请求
(
5
)关闭服务器。
2
、客户方:
(
1
)打开一通信通道,并连接到服务器所在主机的特定端口
。
(
2
)向
服务器发送服务请求报文,等待并接收应答;继续提出请求……
(
3
)请求结束后关闭通信通道并终止。
3
、
TCP
连接的套接字的系统调用时序图如图
2.1
所示。
4
、
TCP
连接的应用程序流程图如图
2.2
所示。
1
图
2.1
TCP
连接的套接字的系统调用时序图
图
2.2
TCP
连接的应用程序流程图
2
四、具体要求
需要有基本的双人、多
人文字聊天功能,上下线通知,在线用户列表,点对
点文件传输,所有的文字或文件传输
需支持
CRC-32
校验,具有出错重传机制;
五、实验代码
(
1
)客户机:
using
System;
using
c;
using
entModel;
using
using
g;
using
using
using
using
s;
using
using
using
namespace
SocketClient
{
public
partial
class
Form1
: Form
{
public
Form1()
{
InitializeComponent();
}
Socket _socketSend;
private
void
btnStart_Click(
object
sender,
EventArgs
e)
{
//
创建负责通信的
Socket
< br>:
if
(_socketSend ==
null
|| _ted ==
false
)
{
_socketSend =
new
Socket(etwork, ,
);
IPAddress ip = ();
IPEndPoint point =
new
IPEndPoint(ip,
Convert
.ToInt32());
SocketAsyncEventArgs socketE =
new
SocketAsyncEventArgs();
ted +=
socketE_Completed;
3
EndPoint =
point;
try
{
_tAsync(socketE);
}
catch
(SocketException)
{
}
}
else
{
ShowMsg(
p>
系统提示:
,
<
/p>
已经连接到服务器:
+
_ng() +
请重新连接!
);
}
}
void
socketE_Completed(
object
sender, SocketAsyncEventArgs e)
{
Socket acceptSocket =
tSocket;
if
(acceptSocket ==
null
)
{
ShowMsg(
p>
系统提示:
,
向
+
ng() +
的连接建立失
败!
p>
);
return
;
}
string
endPoint = ng();
ShowMsg(
< br>系统提示:
,
向
+
endPoint +
的连接成功建立!
);
while
(
true
)
{
//
< br>客户端连接成功后,客户端应该接受服务器发来的消息
byte
[] buffer =
new
byte
[1024 * 1024 * 2];
//
实际接受到的有效字节数
int
r = 0;
try
{
r = e(buffer);
}
catch
(SocketException)
{
r = 0;
}
if
(r == 0)
4
{
if
(ted)
{
ShowMsg(
系统提示:
,
向
+
endPoint +
的连接断开!
);
();
}
break
;
}
//
如果发送的数据是文字(标识
0
)
if
(buffer[0] == 0)
{
string
str =
Encoding
.ing(buffer, 1, r -
1);
ShowMsg(endPoint +
:
,
str);
}
else
if
(buffer[0] == 1)
{
string
fileName =
Encoding
.ing(buffer, 17,
1000).Trim(
'0'
);
gle().LastSendedFile =
Path
.GetTempFileName();
using
(
FileStream
fsWrite =
new
FileStream
(gle().LastSendedFile,
FileMode
.OpenOrCreate,
FileAccess
.Write))
{
(buffer, 0, r);
}
ShowMsg(endPoint +
:
,
给你发送了文件:
+ fileName);
}
else
if
(buffer[0] == 2)
{
gle().IsMove =
true
;
}
else
{
ShowMsg(
系统消息:
,
无法识别“
+ endPoint +
”发送来的消息类型!
);
}
}
}
private
void
Received()
{
5
this
.Activate();
}
private
void
MoveForm()
{
Received();
Random
r =
new
Random
();
Point location =
this
.Location;
DateTime
time =
DateTime
.Now;
while
((
DateTime
.Now - time) <
TimeSpan
.FromSeconds(1.5))
{
Point nextPoint =
new
Point(location.X + (-10, 11), location.Y +
(-10, 11));
this
.Location = nextPoint;
ing.
Thread
.Sleep(10);
}
this
.Location = location;
}
private
void
btnSendMsg_Click(
object
sender,
EventArgs
e)
{
if
(_socketSend ==
null
|| _ted ==
false
)
{
ShowMsg(
p>
系统提示:
,
<
/p>
请先连接服务器,再发送消息!
);
return
;
}
string
endPoint = _ng();
byte
[] basicBuffer =
Encoding
.es();
List
<
byte
< br>> list =
new
L
ist
<
byte
>( + 1);
(0);
ge(basicBuffer);
byte
[] buffer = y();
list =
null
;
try
{
_(buffer);
ShowMsg(
向
< br> + endPoint +
发送:
,
);
}
catch
(SocketException)
{
}
();
}
6
private
void
ShowMsg(
string
sender,
string
msg)
{
string
time =
Dat
eTime
.ng(
);
gle().Line(time +
+ sender);
gle().Line(msg);
gle().Line();
}
private
void
timerChange_Tick(
object
sender,
EventArgs
e)
{
=
DateTime
.ng();
//txtLog
的数据
if
(!txtLogUserChange && !( ==
gle().ng()))
{
txtLogAutoChange =
true
;
= gle().ng();
txtLogAutoChange =
false
;
}
//
是否震动
if
(gle().IsMove)
{
MoveForm();
gle().IsMove =
false
;
}
}
bool
txtLogUserChange =
false
,
txtLogAutoChange =
false
;
private
void
txtLog_TextChanged(
object
sender,
EventArgs
e)
{
if
(txtLogAutoChange)
return
;
txtLogUserChange =
true
;
}
private
void
btnClose_Click(
object
sender,
EventArgs
e)
{
if
(_socketSend !=
null
|| _ted ==
true
)
{
ShowMsg(
p>
系统提示:
,
<
/p>
服务器已经断开或未连接!
);
return
;
}
try
{
7
ShowMsg(
系统提示:
,
向
+
_ng() +
的连接断开!
);
_();
}
catch
(SocketException)
{
}
}
private
void
btnMoveForm_Click(
object
sender,
EventArgs
e)
{
if
(_socketSend ==
null
|| _ted ==
false
)
{
ShowMsg(
p>
系统提示:
,
<
/p>
请先连接服务器,再发送消息!
);
return
;
}
string
endPoint = _ng();
byte
[] buffer =
new
byte
[1] { 2 };
try
{
_(buffer);
ShowMsg(
向
< br> + endPoint +
发送:
, <
/p>
你给对方发送了一个震动!
);
}
catch
(SocketException)
{
}
MoveForm();
}
private
void
btnReceiveFile_Click(
object
sender,
EventArgs
e)
{
if
(
string
.IsNullOrEmpty(gle().LastSendedFile))
{
ShowMsg(
系统提示:
,
目前没有接收到任何的文件!
);
return
;
}
byte
[] buffer =
new
byte
[1024 * 1024 * 5 +
1024];
int
r;
using
(
FileStream
fsRead =
new
FileStream
(gle().LastSendedFile,
FileMode
.OpenOrCreate,
FileAccess
.Read))
8
{
r = (buffer, 0, );
}
byte
[] guidb =
new
byte
[16];
for
(
int
i = 0; i < i++)
{
guidb[i] = buffer[i + 1];
}
Guid
guid =
new
Guid
p>
(guidb);
//buffer, 1,
16);
string
fileName =
Encoding
.ing(buffer, 17,
1000).Trim(
'0'
);
SaveFileDialog sfd =
new
SaveFileDialog();
me =
fileName;
tExt =
Path
.GetExtension(fileName);
=
所有
文件
|*.*
;
=
请选择需要保存的路径
;
if
(alog() == )
{
using
(
FileStream
fsWrite =
new
FileStream
(me,
FileMode
.OpenOrCreate,
FileAccess
.Write))
{
(buffer, 1024, r - 1024);
}
ShowMsg(<
/p>
系统提示:
,
保存文件成功!
);
}
}
private
void
btnSendFile_Click(
object
sender,
EventArgs
e)
{
if
(_socketSend ==
null
|| _ted ==
false
)
{
ShowMsg(
p>
系统提示:
,
<
/p>
请先连接服务器,再发送消息!
);
return
;
}
string
endPoint = _ng();
OpenFileDialog ofd =
new
OpenFileDialog();
=
所有文件
|*.*
;
=
请选
择要发送的文件
;
ileExists =
true
;
if
(alog() == )
{
string
fileName = me;
9
if
(
File
.Exists(fileName))
{
using
(
FileStream
fsReader =
new
FileStream
(fileName,
FileMode
.Open,
FileAccess
.Read))
{
byte
[] buffer =
new
byte
[1024 * 1024 * 5 +
1024];
int
r = (buffer, 1024, -
1024);
if
( < - 1024)
{
buffer[0]
= 1;
byte
[] nameBuffer =
< br>Encoding
.es(
Path
.GetFileName(fileName));
if
( > 1000)
return
;
byte
[] guidBuffer =
< br>Guid
.NewGuid().ToByteArray();
(buffer,
1);
(buffer, 17);
try
{
_(buffer, r + 1024, );
ShowMsg(
向
< br> + endPoint +
发送:
,
你给对方发送了文件:
+
Path
.GetFileName(fileName));
}
catch
(SocketException)
{
}
}
else
{
ShowMsg(<
/p>
系统消息:
,
所选择的文件太大!
< br>);
}
}
}
else
{
ShowMsg(
系统消息:
,
< br>
所选择的文件不存在!
);
}
}
}
}
}
10
-
-
-
-
-
-
-
-
-
上一篇:钻井常用英语
下一篇:3D max中英文对照表