当前位置:文档之家› 单线程的简单QQ聊天系统

单线程的简单QQ聊天系统

单线程的简单QQ聊天系统
单线程的简单QQ聊天系统

苏州高博软件技术职业学院毕业论文

苏州高博软件技术职业学院

毕业设计(论文)报告

系别软件工程系

专业软件开发

班级0801

姓名张蕾蕾

学号008320102

设计题目单线程的简单QQ聊天系统

指导教师陈勇

起迄日期 2010.12.02 - 2011. 1.09

苏州高博软件技术职业学院

毕业设计诚信承诺书

本人慎重承诺和声明:

我承诺在毕业设计过程中严格遵守学校有关规定,在指导教师的安排与指导下完成所规定的毕业设计工作,绝不弄虚作假,不请别人代做毕业设计或抄袭别人的成果。所撰写的毕业论文或毕业设计是在指导老师的指导下自主完成,文中所有引文或引用数据、图表均注明来源,本人愿意为由此引起的后果承担责任。

学生签名:张蕾蕾日期: 2010 年 12 月 02 日

毕业设计知识产权权属声明

本人在老师指导下所完成的论文及设计成果、知识产权归属学校。学校享有以任何方式发表、复制、公开阅览、借阅以及申请专利等权利。

学生签名:张蕾蕾日期: 2010 年 12 月 02 日

指导教师签名:日期:年月日

单线程的简单QQ聊天系统

摘要

目前网络通讯是计算机用户进行交流最普遍的方式,各种各样基于网络的应用也随之诞生,比如“腾讯QQ”——一款基于Internet的即时通信(IM)软件,它使人们能随时在网上与其他用户交换消息,为网络用户提供一个即时交流聊天的平台。但是一般来讲QQ聊天系统是多线程的,因此会涉及到阻塞的问题,如果是单线程的话,线程阻塞在accept方法上时整个进程就不能处理其他事件。本文采用timer控件和socket类中的poll方法相结合的方法进行设计,使用单线程实现了聊天系统,并且不会出现进程阻塞,实质上是采用轮询和查询状态的方式避免了阻塞。本文的设计是在Visual C#2008语言下实现并通过了初步的测试,证明设计是有效的。

关键词timer控件;套接字Socket;单线程

目录

第1章绪论 (1)

1.1引言 (1)

1.1.1 编写目的 (1)

1.1.2背景 (1)

1.2课题意义 (1)

1.3研究现状 (2)

第2章系统分析概述 (3)

2.1可行性研究 (3)

2.1.1技术可行性 (3)

2.1.2经济可行性 (3)

2.1.3操作可行性 (3)

2.2系统分析 (3)

2.2.1功能要求 (3)

2.2.2设计流程图 (4)

第3章总体设计 (5)

3.1体系结构设计 (5)

3.2功能简介 (5)

3.2.1服务器端总体设计 (5)

3.2.2客户端总体设计 (5)

3.3系统特点 (5)

第4章详细设计 (7)

4.1系统的开发工具 (7)

4.1.1开发环境-- Microsoft Visual Studio 2008 (7)

4.1.2C#程序语言 (7)

4.2服务器模块设计 (7)

4.2.1服务器登录模块 (7)

4.2.2服务器聊天模块 (9)

4.3客户端模块设计 (12)

4.3.1客户端登录模块 (12)

4.3.2客户端聊天模块 (14)

结论 (18)

致谢 (19)

第1章绪论

1.1引言

随着互联网应用越来越丰富,以快速、交互、简便为代表的即时通讯工具,已经成为当前网络用户最喜爱的网络沟通工具。作为即时通讯工具最具增长潜力之一的聊天软件,不仅在基础应用方面,还是产品扩展应用方面都将有质的飞跃,极大程度上方便了处于在世界各地的友人之间的相互联系。特别是在近几年,即时通讯工具已经成为一个集互动交流、休闲娱乐、信息管理为一体的多元化互联网应用平台。总之,聊天软件的出现给人们彼此之间的沟通带来了无比的方便,人们可以通过聊天软件建立深刻的友情,它必定会成为人们网络生活不可缺少的一部分。

1.1.1 编写目的

综合运用计算机网络应用编程中的TCP网络通信协议以及Socket套接字等知识,以Visual C#作为开发平台,编写一个单线程聊天程序。本程序需要在一台计算机上运行服务器端程序,然后就可以在同一网络的另外一台计算机上运行客户端程序,登录到服务器上,从而实现服务器与用户之间的即时聊天、发送图片等功能。

1.1.2背景

◆项目名称:简单的单线程QQ聊天系统

◆项目用户:苏州高博软件技术学院3108宿舍

◆开发者:张蕾蕾

1.2课题意义

一直以来,空间上的距离都是人们彼此相互交流的最大障碍。以前人们的信息交流是通过电话、信件、电报等手段,由于功能的局限给收发双方带来了很多不便。所以更加即时的直观的使人们能在网上识别在线用户并与他们实时交换消息的即时通信技术应运而生,它是电子邮件发明以来迅速崛起的在线通讯方式,为网络用户提供一个实时交流聊天的平台。而且即时通信和社会化网络、统一通信、在线协同三大技术热点的关系将越来越密切,已经构成融合发展的趋势,因

此即时通信技术的应用将越来越广泛,越来越普遍。

1.3研究现状

即时消息系统是一种在后PC 时代兴起的,以Internet 网络为基础的,允许交互双方即时地传送文字、语音、视频等信息,能够跟踪网络用户在线状态的网络应用软件,它的出现改变了人们的沟通方式和交友文化,大大拓展了个人生活交流的空间。

第2章系统分析概述

2.1可行性研究

2.1.1技术可行性

随着互联网应用越来越丰富,以快速、交互、简便为代表的即时通讯工具,已经成为当前网络用户最喜爱的网络沟通工具。本系统是一个使用套接字Socket编程,采用其中的TCP面向连接方式的简单的聊天工具,具有很强的实用价值。

2.1.2经济可行性

开发本系统能够使人们之间的交流带来极大的方便,而且所用的人力、物力、技术、资金等的花费不大,所以今后获得的经济效益一定会大于开发成本。

2.1.3操作可行性

本开发系统操作步骤简单,运行时只要在登录时输入服务器信息以及自己的昵称就可以进入聊天程序,然后就可以与服务器进行信息交流。

2.2系统分析

2.2.1功能要求

ⅰ.客户端登录时输入的服务器信息必须与服务端一致。

ⅱ.用户与服务器之间的信息发送,是本程序需要实现的最基本的功能。

ⅲ.在C/S模式中,服务器和客户端是相互依赖的。服务器启动以后,客户端才能连接上服务器,如果服务器没有启动,那么用户和服务器不能连接而且客户端或服务器任意一方断开连接,对方都会能接收到通知消息。

2.2.2设计流程图

第3章 总体设计

3.1 体系结构设计

通常的通信工具,都采用客户机/服务器(C/S)体系结构,C/S 结构包括一个客户端和一个服务器。在Internet 通信中,使用TCP 面向连接的套接字来建立服务器端和客户端两个IP 地址端点之间的会话。一旦建立了这种连接,就可以在设备之间可靠地传输数据。如下图所示:

3.2 功能简介

本聊天程序提供了服务器与客户端的一对一连接,客户端必须在服务器启动以后才能连接成功。用户登录以后聊天室的客户端会显示用户已登录和在线时间,还可以与服务器进行即时聊天等。 3.2.1 服务器端总体设计

对于服务器端程序,首先建立的套接字Socket 必须用Bind 方法绑定到Tcp 通信的本地IP 地址和端口上,当套接字绑定到本地,使用Listen 方法等待客户机发出的连接尝试,接着服务器使用Accept 方法为接收任何引进连接做准备,在接受客户端连接之后,客户端和服务器通过Receive 方法和Send 方法传输数据。

3.2.2 客户端总体设计

对于客户端程序,客户机通过Connect 方法把一个地址绑定到创建的Socket 对象,一旦客户端与服务器建立连接,客户机就可以像服务器收发数据使用的方法一样,使用Send 和Receive 方法进行通信。

3.3 系统特点

界面设计美观友好。

规范、完整的基础信息设置。

客户端

服务器

能够即时进行通信聊天。 系统运行稳定、安全可靠。

第4章详细设计

4.1系统的开发工具

4.1.1开发环境-- Microsoft Visual Studio 2008

Visual Studio是微软公司出品的一款大型应用软件,是一套完整的开发工具集,它主要用于生成https://www.doczj.com/doc/724376902.html, Web应用程序、XML Web Services、桌面应用程序和移动应用程序。

4.1.2 C#程序语言

C#是微软为.NET Framework量身订做的程序语言,它拥有C/C++的强大功能以及Visual Basic简易使用的特性,是第一个组件导向的程序语言,和C++与Java一样亦为对象导向(object-oriented)程序语言。

4.2服务器模块设计

4.2.1服务器登录模块

登录模块界面

服务器进入登录界面(如图4-2-1)后,设置IP地址和端口号,点击“登录”按钮,系统将验证输入的服务器信息是否合法,如果服务器信息合法则跳转到聊天室,否则将弹出错误提示窗口(如图4-2-2)。如果未设置服务器信息,则弹出信息提示窗口(如图4-2-3);点击“重置”按钮,服务器信息将被清空。

登录模块代码

{

if (txtIP.Text == ""||txtPort .Text =="")

{

MessageBox.Show("请输入IP地址或端口号!", "提示信息", MessageBoxButtons.OK, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button1);

return;

}

else

{

try

{

IPAddress ipadd = IPAddress.Parse(this.txtIP.Text);

int port = Convert.ToInt32(this.txtPort.Text);

this.Text = "服务器" + DateTime.Now.ToString() + " " + DateTime.Now.DayOfWeek.ToString();

richTextBox1.AppendText("System:服务器已进入聊天室!<-" + DateTime.Now.ToLongTimeString() + "->.....\r\n");

string SerIp = txtIP.Text.ToString();

string SerPort = txtPort.Text.ToString();

labip.Text = " IP地址:" + " " + SerIp + " ";

labport.Text = " 端口号:" + " " + SerPort;

}

catch (Exception)

{

MessageBox.Show("您输入的IP地址或端口号不正确,\n请重新输入!", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);

}

}

}

4.2.2服务器聊天模块

聊天模块界面

另外聊天室的工具栏还有一些辅助按钮,如“背景颜色”按钮(如图4-2-5);“隐藏窗口”按钮,隐藏聊天程序、“帮助”按钮(如图4-2-6)、“关于”按钮(如图4-2-7)。

{

try

{

IPAddress ip = IPAddress.Parse(this.txtIP.Text);

IPEndPoint myEndPoint = new IPEndPoint(ip, Int32.Parse(this.txtPort.Text));

serTcpSocket = new TcpListener(myEndPoint);

serTcpSocket.Start(3);

this.Text = " 服务器Taking....";

richTextBox1.Clear();

richTextBox1.AppendText("System:服务器已启动!<-" + DateTime.Now.ToLongTimeString() + "->.....\r\n");

btn_start.Enabled = false;

btn_stop.Enabled = true;

timerAccept.Enabled = true;

timerReceive.Enabled = true;

}

catch (Exception ex)

{

MessageBox.Show("您输入的IP地址或端口号不正确,\n请重新输入!", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);

return;

}

}

private void btn_send_Click(object sender, EventArgs e)

{

int index = comboBoxClientIP.SelectedIndex;

if (comboBoxClientIP.SelectedIndex == -1)

{

MessageBox.Show("您未选择发送端", "为空", MessageBoxButtons.OK, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button1);

return;

}

try

{

if (txt1_sendinfo.Text == "")

{

MessageBox.Show("您输入的消息为空", "为空", MessageBoxButtons.OK, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button1);

return;

}

else

{

string str = Dns.GetHostName() + ":" + richTextBox1.Text + "\n";

sendBuffer = System.Text.Encoding.UTF8.GetBytes(str);

((User)conArrayList[index ]).conNetworkStream.Write(sendBuffer, 0, sendBuffer.Length);

richTextBox1.SelectionColor = Color.SteelBlue;

richTextBox1.AppendText(str + '\n');

txt1_sendinfo.Clear();

}

}

catch (Exception ex)

{

MessageBox.Show("发送失败!", "系统提示", MessageBoxButtons.YesNo, MessageBoxIcon.Warning);

}

}

private void timerAccept_Tick(object sender, EventArgs e)

{

if (serTcpSocket.Pending())

{

TcpClient conTcpSocket;

conTcpSocket = serTcpSocket.AcceptTcpClient();

User oneUser = new User(conTcpSocket);//添加对象

conArrayList.Add(oneUser);//添加对象

richTextBox1.AppendText("System:已有用户" + conTcpSocket.Client.RemoteEndPoint + "连上.....\r\n");

}

catch (Exception ex)

{

MessageBox.Show("服务器: " + ex.Message);

this.btn_start.Enabled = true;

}

}

private void timerReceive_Tick(object sender, EventArgs e)

{

for (int i = 0; i < conArrayList.Count; i++)

{

if (((User)conArrayList[i]).conTcpSocket.Client.Poll(10,

SelectMode.SelectRead))

{

int count = 0;

if (((User)conArrayList[i]).conNetworkStream.DataAvailable)

{

count = ((User)conArrayList[i]).conNetworkStream.Read(recBuffer, 0, recBuffer.Length);

string s = System.Text.Encoding.UTF8.GetString(recBuffer, 0, count);

richTextBox1.AppendText(s + '\n');

}

else

{

richTextBox1.AppendText(((User)conArrayList[i]).conTcpSocket.Client.RemoteEndPoint + "已断开");

((User)conArrayList[i]).conTcpSocket.Client.Close();

((User)conArrayList[i]).conTcpSocket.Close();

((User)conArrayList[i]).conNetworkStream.Close();

conArrayList.RemoveAt(i);

comboBoxClientIP.Items.RemoveAt(i);

comboBoxClientIP.Text = "请选择客户端";

}

}

}

}

4.3客户端模块设计

4.3.1客户端登录模块

登录模块界面

客户端进入登录界面(如图4-3-1),输入服务器IP地址和端口号以及自己的昵称,点击“登录”按钮,系统将验证输入的服务器信息是否合法,如果合法

则跳转到聊天室,否则弹出错误对话框(如图4-3-2)。如果未输入服务器信息则弹出提示提示(如图4-3-3).;如果未输入昵称则弹出提示信息提示(如图4-3-4)。

private void btnLog_Click(object sender, EventArgs e)

{

if (txt_IP.Text == "" || txt_Port.Text == "")

{

MessageBox.Show("服务器信息不能为空!", "提示信息", MessageBoxButtons.OK, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button1);

return;

}

else

{

try

{

IPAddress ipadd = IPAddress.Parse(this.txt_IP.Text);

int port = Convert.ToInt32(this.txt_Port.Text);

tab1.Visible = false;

tab2.Visible = true;

this.btnImgFile.Enabled = false;

this.Text = "客户端" + DateTime.Now.ToString() + " " + DateTime.Now.DayOfWeek.ToString();

richTextBox1.AppendText("System:" + " 客户端已进入聊天室!<-" + DateTime.Now.ToLongTimeString() + "->.....\r\n");

string SerIp = txt_IP.Text.ToString();

string SerPort = txt_Port.Text.ToString();

lbSerIp.Text = " IP地址:" + " " + SerIp + " ";

lbSerPort.Text = " 端口号:" + " " + SerPort;

}

catch (Exception err)

{

MessageBox.Show("您输入的服务器信息不合法,\n请重新输入!", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);

}

}

4.3.2客户端聊天模块

聊天模块界面

另外聊天室的工具栏还有一些辅助按钮,如“背景颜色”按钮(如图4-3-6);“隐藏窗口”按钮;“帮助”按钮(如图4-3-7);“关于”按钮(如图4-3-8)。

图4-3-7 关于对话框

聊天室模块代码

private void btn_req_Click(object sender, EventArgs e) {

try {

cliTcpClient = new TcpClient();

IPAddress ip = IPAddress.Parse(this.txt_IP.Text);

myEndPoint = new IPEndPoint(ip, Int32.Parse(this.txt_Port.Text)); this.Text = " " + "客户端 Taking...."; richTextBox1.Clear();

richTextBox1.AppendText("System :客户端连接到服务器!<-" + DateTime.Now.ToLongTimeString() + "->.....\r\n"); btn_req.Enabled = false; btn_close.Enabled = true; timerConnect.Enabled = true; } catch {

richTextBox1.Clear();

richTextBox1.AppendText("System :客户端未连接上服务器!<-" + DateTime.Now.ToLongTimeString() + "->.....\r\n"); return; } }

private void btn_send_Click(object sender, EventArgs e) {

try {

if (txt2_send.Text == "")

{

MessageBox.Show("您输入的消息为空", "为空", MessageBoxButtons.OK, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button1);

return;

}

string str = Dns.GetHostName() + ":" +richTextBox1. Text + "\n";

sendBuffer = System.Text.Encoding.UTF8.GetBytes(str);

conUser.conNetworkStream.Write(sendBuffer, 0, sendBuffer.Length);

richTextBox1.SelectionColor = Color.LightCoral;

richTextBox1.AppendText(str + '\n');

txt2_send.Clear();

}

catch (Exception ex)

{

MessageBox.Show("发送失败!", "系统提示", MessageBoxButtons.YesNo, MessageBoxIcon.Warning);

}

}

private void timerReceieve_Tick(object sender, EventArgs e)

{

if (conUser.conTcpClient.Client.Poll(10, SelectMode.SelectRead))

{

if (conUser.conNetworkStream.DataAvailable)

{

int count = conUser.conNetworkStream.Read(recBuffer, 0, recBuffer.Length);

string str = System.Text.Encoding.UTF8.GetString(recBuffer, 0, count);

richTextBox1. AppendText(str + '\n');

}

else

{

richTextBox1.AppendText("已和主机" +

conUser.conTcpClient.Client.RemoteEndPoint + "断开连接" + '\n');

timerReceieve. Enabled = false;

btn_send. Enabled = false;

btn_close. Enabled = false;

btn_req. Enabled = true;

}

}

}

private void timerConnect_Tick(object sender, EventArgs e)

{

try

相关主题
文本预览
相关文档 最新文档