网络编程文档.docx

上传人:b****8 文档编号:29408061 上传时间:2023-07-23 格式:DOCX 页数:23 大小:163.79KB
下载 相关 举报
网络编程文档.docx_第1页
第1页 / 共23页
网络编程文档.docx_第2页
第2页 / 共23页
网络编程文档.docx_第3页
第3页 / 共23页
网络编程文档.docx_第4页
第4页 / 共23页
网络编程文档.docx_第5页
第5页 / 共23页
点击查看更多>>
下载资源
资源描述

网络编程文档.docx

《网络编程文档.docx》由会员分享,可在线阅读,更多相关《网络编程文档.docx(23页珍藏版)》请在冰豆网上搜索。

网络编程文档.docx

网络编程文档

网络应用编程文档

 

项目名称:

简单的聊天软件

姓名:

学号:

(下载源码就到新兴网络:

www.NewX)

2009年4月26日

目录

一.需求分析3

1.1开发背景3

1.2功能要求3

1.3运行环境3

1.4功能实现4

二.项目设计5

2.1程序流图5

2.2概要设计6

2.3功能设计6

2.4详细设计8

2.4.1界面设计8

客户端9

2.4.2程序结构设计10

3.1、客户端10

3.2服务器端16

四项目测试18

五、总结:

18

一.需求分析

1.1开发背景

在网络越来越发达的今天,人们对网络的依赖越来越多,越来越离不开网络,由此而产生的聊天工具越来越多,类似QQ、网络聊天时一类的聊天系统的发展日新月异。

但是,QQ等现有的聊天程序也存在着很大的问题。

比如,我在使用QQ的时候,就对他发的各种“广告”深恶痛绝。

对于登陆后时不时弹出的打扰窗口,很是厌烦。

因此我在本次作业的激励下,产生了一个制作类似QQ的网络聊天工具并且“无垃圾信息”洁净聊天工具的想法,而且希望通过制作该程序还能更好的学习网络软件编程知识。

1.2功能要求

(1)登录功能。

(2)客户可以通过服务器转发,实现一对一、一对多和多对多聊天。

(3)实现抖动和声音提醒。

(4)服务器端和客户端程序都能实时显示在线用户数目。

(5)应该具有友好、易用、美观的图形界面。

(6)无垃圾打扰信息

(7)保存和删除聊天信息。

1.3运行环境

本系统基于WINDOWSsocket接口设计,适用于WINDOWSXP等系统。

1.4功能实现

1.登录验证功能。

对于账号重复等异常,需要提示给用户。

2.客户通过服务器转发,实现一对一、一对多和多对多聊天。

3.实时显示目前其它用户的状态,能够提示在线用户数目、状态等。

4.保存并能察看聊天纪录。

5.申请新的用户号码。

6.易用、美观的图形界面,实现系统托盘。

7.收到信息时,能够收到声音等提示信息,发送端还能通过发送抖动,提示聊天的对方。

二.项目设计

2.1程序流图

2.2概要设计

通过C#,实现网络聊天的功能,采用WindowsSocket编程,服务器与客户端采用了TCP/IP连接方式,在设计聊天方案时,实行将所有信息发往服务器端,再由服务器进行分别处理的思路,服务器端是所有信息的中心。

由于服务器端要保存用户信息,我们利用数据库来实现这一功能,因此首先需要建立用户信息数据库。

在客户端保存聊天纪录和用户号码这一功能的实现中,采用了文件系统设计。

在信息到来及好友上线时,通过闪动托盘图标和播放不同的音乐进行提示。

建立消息链表来保存用户接收的各种消息。

 

2.3功能设计

客户端:

1)登陆功能:

建立与服务器的连接并登陆,能显示登陆错误信息。

2)界面显示:

将在线好友显示在好友列表中,并实现系统托盘,加入工具栏便于操作。

3)聊天功能:

与好友聊天。

4)聊天纪录:

能保存聊天纪录,并能察看聊天纪录。

5)信息提示:

闪动托盘图标提示到来信息,并播放不同音乐来提示。

6)发送窗口抖动,发送端提示聊天的对方。

服务器端:

向各个客户端发布系统消息。

接受来自客户端的各种信息并分别处理。

1)登陆信息:

检查登陆信息是否正确,并向客户端返回登陆信息,如信息正确。

就将在线用户发给该用户,并将该用户的状态发给各在线用户。

同时在服务器端显示出来。

2)聊天信息:

转发给消息指定的用户。

3)申请信息:

自动分配8位用户号码,并保存该用户,同时将信息返回给客户端。

4)用户下线:

将此用户下线消息发给各客户端,并改写用户在服务器端的状态。

 

程序中主要变量及函数的功能说明如下:

客户端:

privatevoidlogin_btn_Click(objectsender,EventArgse)---登陆到服务器

privatevoidsvrip_tb_TextChanged(objectsender,EventArgse)设置要连接的服务器的地址端口

privatevoidchatrcd_rtb_TextChanged(objectsender,EventArgse)--显示好友发送的信息

privatevoidsend_btn_Click(objectsender,EventArgse)----给好友发送信息

privatevoiduser_tb_TextChanged(objectsender,EventArgse)-----申请新的用户

privatevoidchatrcd_rtb_TextChanged(objectsender,EventArgse)----显示服务器消息

privatevoidmsg_tb_TextChanged(objectsender,EventArgse)-----显示消息输入文本

privatevoidnudge_pb_Click(objectsender,EventArgse)------发送窗口抖动

privatevoidbroadcast_rb_CheckedChanged(objectsender,EventArgse)------聊天模式的变更

privatevoidhide_cb_CheckedChanged(objectsender,EventArgse)-------最小化到托盘

服务器端:

用户及发送信息结构体类型:

publicvoidStartUp()-------服务器启动,并且实时更新用户在线信息

publicvoidGetConfig()------配置服务器端口号等信息

privatevoidThreadFunc(objectobj)-----系统对于发送消息、发送抖动等的异常的处理

publicvoidClose()--------关闭服务器

2.4详细设计

2.4.1界面设计

客户端

1)登陆界面

2)显示当前状态

3)最小化到托盘

4)发送抖动

5)聊天模式变更

6)发送接收消息

客户端

1)服务器启动配置端口号

2)实时更新在线用户信息

2.4.2程序结构设计

如概要设计反映。

三.编码实现

3.1、客户端

a)登陆

privatevoidlogin_btn_Click(objectsender,EventArgse)

{

//验证数据合法性

if(!

ValidateInfo())

{

return;

}

intport=int.Parse(svrport_tb.Text);

//向服务器发出连接请求

TCPConnectionconn=newTCPConnection(_ipAddr,port);

TcpClient_tcpc=conn.Connect();

if(_tcpc==null)

{

MessageBox.Show("无法连接到服务器,请重试!

",

"错误",

MessageBoxButtons.OK,

MessageBoxIcon.Exclamation);

}

else

{

NetworkStreamnetstream=_tcpc.GetStream();

//向服务器发送用户名以确认身份

netstream.Write(Encoding.Unicode.GetBytes(user_tb.Text),0,Encoding.Unicode.GetBytes(user_tb.Text).Length);

//得到登录结果

byte[]buffer=newbyte[50];

netstream.Read(buffer,0,buffer.Length);

stringconnResult=Encoding.Unicode.GetString(buffer).TrimEnd('\0');

if(connResult.Equals("cmd:

:

Failed"))

{

MessageBox.Show("您的用户名已经被使用,请尝试其他用户名!

",

"提示",

MessageBoxButtons.OK,

MessageBoxIcon.Information);

return;

}

else

{

stringsvrskt=svrip_tb.Text+":

"+svrport_tb.Text;

chat_frmchatFrm=newchat_frm(user_tb.Text,netstream,svrskt);

chatFrm.Owner=this;

this.Hide();

chatFrm.Show();

}

}

}

b)发送消息

privatevoidsend_btn_Click(objectsender,EventArgse)

{

stringlocalTxt=null;

stringsendTxt=null;

stringmsg=msg_tb.Text.Trim();

if(msg==string.Empty)

{

MessageBox.Show("不能发送空消息",

"提示",

MessageBoxButtons.OK,

MessageBoxIcon.Information);

return;

}

//如果是聊天室模式则向服务器发送广播请求

if(broadcast_rb.Checked)

{

localTxt=string.Format("[广播]您在{0}对所有人说:

\r\n{1}\r\n\r\n",DateTime.Now,msg);

sendTxt=string.Format("[广播]{0}在{1}对所有人说:

\r\n{2}\r\n\r\n",_username,DateTime.Now,msg);

//发送广播请求

_nws.Write(newbyte[]{0,5},0,2);

}

else

{

string_receiver=online_cb.Text;

if(_receiver==string.Empty)

{

MessageBox.Show("请选择一个接收者!

\n如果没有接受者可选,表明当前只有您一个人在线\t",

"发送消息",

MessageBoxButtons.OK,

MessageBoxIcon.Information);

return;

}

localTxt=string.Format("[私聊]您在{0}对{1}说:

\r\n{2}\r\n\r\n",DateTime.Now,_receiver,msg);

sendTxt=string.Format("[私聊]{0}在{1}对您说:

\r\n{2}\r\n\r\n",_username,DateTime.Now,msg);

//发送接受者用户名

_nws.Write(Encoding.Unicode.GetBytes(_receiver),0,Encoding.Unicode.GetBytes(_receiver).Length);

}

_nws.Write(Encoding.Unicode.GetBytes(sendTxt),0,Encoding.Unicode.GetBytes(sendTxt).Length);

chatrcd_rtb.AppendText(localTxt);

msg_tb.Clear();

}

///

///有新消息来时闪烁任务栏并且保持聊天记录内容滚动到最底端,QQ就是这么玩滴~

///

///

///

[DllImport("user32.dll")]

publicstaticexternboolFlashWindow(IntPtrhWnd,boolbInvert);

privatevoidchatrcd_rtb_TextChanged(objectsender,EventArgse)

{

chatrcd_rtb.ScrollToCaret();

if(this.WindowState==FormWindowState.Minimized)

{

FlashWindow(this.Handle,true);

}

}

///

///当窗口恢复后取消任务栏的闪烁效果

///当窗口最小化时判断是否要隐藏到系统托盘

///

///

///

privatevoidchat_frm_SizeChanged(objectsender,EventArgse)

{

switch(this.WindowState)

{

caseFormWindowState.Normal:

FlashWindow(this.Handle,false);

break;

caseFormWindowState.Minimized:

if(_hideFlag)

{

notifyIcon1.Visible=true;

this.Visible=false;

}

break;

default:

break;

}

}

///

///在线列表下拉框显示之前向服务器发送请求在线列表的命令

///

///

///

privatevoidonline_cb_DropDown(objectsender,EventArgse)

{

_nws.Write(newbyte[]{0,2},0,2);

}

///

///聊天模式改变

///

///

///

privatevoidbroadcast_rb_CheckedChanged(objectsender,EventArgse)

{

if(private_rb.Checked)

{

online_cb.Enabled=true;

}

else

{

online_cb.Enabled=false;

}

}

///

///设置最小化到系统托盘的标记值

///

///

///

privatevoidhide_cb_CheckedChanged(objectsender,EventArgse)

{

_hideFlag=hide_cb.Checked;

}

///

///产生闪屏振动效果

///

privatevoidNudge()

{

if(notifyIcon1.Visible==true)

{

return;

}

if(this.WindowState==FormWindowState.Minimized)

{

this.WindowState=FormWindowState.Normal;

}

inti=0;

Point_old=this.Location;

Point_new1=newPoint(_old.X+2,_old.Y+2);

Point_new2=newPoint(_old.X-2,_old.Y-2);

_sp2.Play();

while(i<4)

{

this.Location=_new1;

Thread.Sleep(60);

this.Location=_new2;

Thread.Sleep(60);

i++;

}

this.Location=_old;

}

c)发送抖动

privatevoidnudge_pb_Click(objectsender,EventArgse)

{

stringdisplayTxt=null;

if(private_rb.Checked&&online_cb.Text==string.Empty)

{

MessageBox.Show("非聊天室模式下必须先选择一个接收者!

",

"发送闪屏振动",

MessageBoxButtons.OK,

MessageBoxIcon.Information);

return;

}

if(private_rb.Checked)

{

_nws.Write(newbyte[]{0,4},0,2);

string_receiver=online_cb.Text;

_nws.Write(Encoding.Unicode.GetBytes(_receiver),0,Encoding.Unicode.GetBytes(_receiver).Length);

displayTxt=string.Format("[系统提示]您向{0}发送了一个闪屏振动。

\r\n\r\n",_receiver);

}

else

{

_nws.Write(newbyte[]{0,3},0,2);

displayTxt="[系统提示]您向所有人发送了一个闪屏振动。

\r\n\r\n";

}

chatrcd_rtb.AppendText(displayTxt);

Nudge();

}

d)关闭,断开连结

privatevoidclose_btn_Click(objectsender,EventArgse)

{

DialogResultret;

ret=MessageBox.Show("确定与服务器断开连接吗?

",

"退出",

MessageBoxButtons.OKCancel,

MessageBoxIcon.Question,

MessageBoxDefaultButton.Button2);

if(ret==DialogResult.OK)

{

//向服务器发送离线请求

_nws.Write(newbyte[]{0,1},0,2);

//结束接受消息的线程

if(_receiveThread!

=null)

{

_receiveThread.Abort();

}

//关闭网络流

_nws.Close();

//关闭父窗口及自身

this.Owner.Close();

this.Close();

}

}

3.2服务器端

1)配置端口号

publicvoidGetConfig()

{

stringportParam;

Console.Write("请输入监听端口,直接回车则接受默认端口8888:

");

portParam=Console.ReadLine();

if(portParam!

=string.Empty)

{

if(!

int.TryParse(portParam,out_port)||_port<1023||_port>65535)

{

_port=8888;

Console.WriteLine("端口号不合法,默认端口号被接受!

");

}

}

}

2)启动服务器,监听客户端状态,实时变更

publicvoidStartUp()

{

IPAddress_ip=Dns.GetHostAddresses(Dns.GetHostName())[0];

_tcpl=newTcpListener(_ip,_port);

_tcpl.Start();

Console.WriteLine("服务器已启动,正在监听...\n");

Console.WriteLine(string.Format("服务器IP:

{0}\t端口号:

{1}\n",_ip,_port));

while(true)

{

byte[]packetBuff=newbyte[_maxPacket];

SocketnewClient=_tcpl.AcceptSocket();

newClient.Receive(packetBuff);

stringuserName=Encoding.Unicode.GetString(packetBuff).TrimEnd('\0');

//验证是否为唯一用户

if(_transmit_tb.Count!

=0&&_transmit_tb.ContainsKey(userName))

{

newClient.Send(Encoding.Unicode.GetBytes("cmd:

:

Failed"));

continue;

}

else

{

newClient.Send(Encoding.Unicode.GetBytes("cmd:

:

Successful"));

}

//将新连接加入转发表并创建线程为其服务

_transmit_tb.Add(userName,newClient);

stringsvrlog=string.Format("[系统消息]新用户{0}在{1}已连接...当前在线人数:

{2}\r\n\r\n",userName,DateTime.Now,_transmit_tb.Count);

Console.WriteLine(svrlog);

ThreadclientThread=newThread(newParameteri

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 农林牧渔 > 林学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1