QQ聊天程序的网络通信原理及编程
- 格式:pdf
- 大小:156.20 KB
- 文档页数:16
TCP/UDP程序开发使用C#制作简易qqTCP、UDP程序开发一.实验课时8学时二.实验目的开发TCP/UDP协议应用程序,掌握网络应用程序的工作原理。
通过本实验,深入理解TCP和UDP协议的异同点,了解网络协议的工作过程,学会网络通信编程的基本方法,能够编制网络应用程序。
三.实验内容(1)了解和掌握“基于UDP——面向无连接的应用程序”和“基于TCP——面向连接的应用程序”的运行机制和编程方法。
(2)选择以下一个内容,编写一个网络通信应用程序①聊天程序;②邮件收发程序;③HTTP服务器程序。
四.实验要求(1)使用任意编程语言(如Java,C,VB,Delphi等)编写基于TCP或UDP协议的网络应用程序。
(2)总结实验过程,内容包括:方案、程序、调试、结果、分析、结论。
五.实验设备(1)硬件要求:计算机、Internet网。
(2)软件要求:Windows操作系统、相关软件开发工具(如Microsoft Visual Studio,JDK等)。
六.预习要求(1)复习TCP/UDP协议原理。
(2)复习应用进程跨越网络通信的基本编程方法。
(3)复习聊天、邮件、HTTP服务的相关原理。
(4)熟悉相关编程语言及编程工具环境。
七.注意事项(1)遵守实验纪律,爱护实验设备。
(2)提交详细实验报告一份。
实验过程和结果不能简单地复制相关命令或内容,要有理解和分析。
八.程序代码1.服务器端using System;using System.Collections.Generic;using ponentModel;using System.Data;using System.Drawing;using System.Linq;using System.Text;using System.Windows.Forms;using ;using .Sockets;using System.Threading;using System.IO;namespace WindowsFormsApplication1{public partial class Form1 : Form{public Form1(){InitializeComponent();this.Init();tab2.Visible = true;tab3.Visible = false;tab1.Visible = false;}private void btnLog_Click(object sender, EventArgs e){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);tab3.Visible = true;tab1.Visible = true;this.Init2();this.btnImgFile.Enabled = false;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);}}}//重置服务器信息private void btnResent_Click_1(object sender, EventArgs e){txtIP.Clear();txtPort.Clear();}private void Init(){richTextBox1.Visible = false;txt1_sendinfo.Visible = false;}private void Init2(){richTextBox1.Visible = true;txt1_sendinfo.Visible = true;}private OpenFileDialog openfiledialog = new OpenFileDialog();private SaveFileDialog savefiledialog = new SaveFileDialog();private byte[] img;//传输图片用字节数组private int imgflag = 0;private FileStream fstream;public delegate void UpdateRichTextBox(string msg);//异步委托代理public delegate void UpdateImg(Stream s);private Socket socket; //服务器端套接字private Socket clientSocket; //客户端连接套接字private Thread thread;//启动服务器,开始监听private void btn_start_Click(object sender, EventArgs e){try{IPAddress ip = IPAddress.Parse(this.txtIP.Text);IPEndPoint server = new IPEndPoint(ip, Int32.Parse(this.txtPort.Text));//创建服务器套接字socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);socket.Bind(server);//绑定端口号socket.Listen(10);thread = new Thread(new ThreadStart(AcceptMessage));thread.Start();//开始监听this.Text = " 服务器Taking....";richTextBox1.Clear();richTextBox1.AppendText("System:服务器已启动!<-"+ DateTime.Now.ToLongTimeString() + "->.....\r\n");btnImgFile.Enabled = true;btn_start.Enabled = false;btn_stop.Enabled = true;}catch (Exception ex){MessageBox.Show("服务器: " + ex.Message);this.btn_start.Enabled = true;}}//接收客户端信息public void AcceptMessage() //异步接收信息后台线程方法{this.clientSocket = socket.Accept();this.richTextBox1.Clear();richTextBox1.AppendText("System:服务器连接成功!?<-"+ DateTime.Now.ToLongTimeString() + "->.....\r\n");while (true){try{if(this.clientSocket == null|| this.clientSocket.Connected == false)break;NetworkStream netStream = new NetworkStream(this.clientSocket);//通过clientSocket对象获取NetworkStream对象//得到一条消息的长度byte[] dataSize = new byte[4];netStream.Read(dataSize, 0, 4);int size = System.BitConverter.ToInt32(dataSize, 0);//循环接收直到一条完整的消息全部读入到字节数组中byte[] message = new byte[size];int dataleft = size;int start = 0;if (size > 0){while (dataleft > 0){int recv = netStream.Read(message, start, dataleft);start += recv;dataleft -= recv;}if (message[0] == 101)//101代表传输图片{MemoryStream ms = new MemoryStream(message, 1, message.Length - 1);richTextBox1.BeginInvoke(new UpdateImg(ViewImg), new object[] { ms });}else//默认进行普通传输{string Msg = System.Text.Encoding.Unicode.GetString(message, 1, message.Length - 1);this.richTextBox1.BeginInvoke(newUpdateRichTextBox(UpdateMessage), new object[] { Msg });}}Thread.Sleep(100);}catch (.Sockets.SocketException se){MessageBox.Show("服务器:" + se.Message);}}}//点击“发送”按钮private void btn_send_Click(object sender, EventArgs e){if (txt1_sendinfo.Text == ""){MessageBox.Show("请先输入内容!");txt1_sendinfo.Clear();txt1_sendinfo.Focus();return;}if (imgflag == 1){//发送图片?byte[] imgSize = new byte[4];//将32位整数值转换为字节数组imgSize = System.BitConverter.GetBytes(img.Length + 1);//其中加1是因为后面了一个101做分隔符try{NetworkStream netStream = new NetworkStream(clientSocket);netStream.Write(imgSize, 0, 4);netStream.WriteByte(101);//分隔符netStream.Write(img, 0, img.Length);netStream.Flush();this.richTextBox1.SelectionColor = Color.SteelBlue;this.richTextBox1.AppendText("服务器<-"+ DateTime.Now.ToLongTimeString() + "->:\r\n");this.richTextBox1.SelectionStart = this.richTextBox1.Text.Length;Clipboard.SetDataObject(Image.FromStream(fstream));richTextBox1.Paste();this.richTextBox1.SelectionColor = Color.SteelBlue;this.richTextBox1.AppendText("\n");fstream.Flush();fstream.Close();//此流必须在这里才可以消除txt1_sendinfo.Paste();this.richTextBox1.SelectionStart = this.richTextBox1.Text.Length;this.richTextBox1.Focus();this.txt1_sendinfo.Text = "";this.txt1_sendinfo.Focus();imgflag = 0;//复原return;//不执行后面的传输文本信息}catch (System.Exception ex){MessageBox.Show("服务器:" + ex.Message);}}//发送文本信息this.richTextBox1.SelectionColor = Color.SteelBlue;string str = "服务器<-"+ DateTime.Now.ToLongTimeString() + "->:\r\n"+ txt1_sendinfo.Text;int i = str.Length;if (i == 0){return;}else{//因为str为Unicode编码,每个字符占2个字节,所以实际字节数应为字符个数*2 i *= 2;}byte[] dataSize = new byte[4];//将32位整数值转换为字节数组dataSize = System.BitConverter.GetBytes(i + 1);//其中加1是因为后面写了一个1做分隔符byte[] sendbytes = System.Text.Encoding.Unicode.GetBytes(str);try{NetworkStream netStream = new NetworkStream(clientSocket);netStream.Write(dataSize, 0, 4);netStream.WriteByte(1);//分隔符netStream.Write(sendbytes, 0, sendbytes.Length);netStream.Flush();richTextBox1.SelectionColor = Color.SteelBlue;this.richTextBox1.AppendText(str + "\n");this.richTextBox1.SelectionStart = this.richTextBox1.Text.Length;this.richTextBox1.Focus();this.txt1_sendinfo.Rtf = "";this.txt1_sendinfo.Focus();}catch (System.Exception ex){MessageBox.Show("服务器:" + ex.Message);}}//断开连接private void btn_stop_Click(object sender, EventArgs e){socket.Close();thread.Abort();thread.Join(10);this.btn_start.Enabled = true;btn_stop.Enabled = false;this.btnImgFile.Enabled = false;this.Text = " 服务器"+ DateTime.Now.ToString() + " "+ DateTime.Now.DayOfWeek.ToString();this.richTextBox1.AppendText("System:服务器断开连接!<-"+ DateTime.Now.ToLongTimeString() + "->..... \r\n");}//接收文本private void UpdateMessage(string strmsg) //将异步接收到的信息显示在文本框里{this.richTextBox1.SelectionColor = Color.LightCoral;this.richTextBox1.AppendText(strmsg + "\n");this.richTextBox1.SelectionStart = this.richTextBox1.Text.Length;this.richTextBox1.Focus();this.txt1_sendinfo.Focus();}//接收图片信息private void ViewImg(Stream s) //将异步接收到的信息显示在文本框里{richTextBox1.SelectionStart = richTextBox1.Text.Length;richTextBox1.SelectionColor = Color.LightCoral;richTextBox1.AppendText("服务器接收图片<-"+ DateTime.Now.ToLongTimeString() + "->:\r\n");Clipboard.SetDataObject(Image.FromStream(s));//利用剪切板richTextBox1.Paste();richTextBox1.SelectionColor = Color.LightCoral;richTextBox1.AppendText("\n");richTextBox1.SelectionStart = richTextBox1.Text.Length;richTextBox1.Focus();txt1_sendinfo.Focus();}//上传图片文件中的图片private void btnImgFile_Click(object sender, EventArgs e){openfiledialog.Filter = "所有文件t(*.*)|*.*|位图文(*.bmp)|*.bmp|文件t (.jpg)|*.jpg|文件t(.gif)|*.gif";if (openfiledialog.ShowDialog() == DialogResult.OK){String strpath = openfiledialog.FileName;fstream = new FileStream(strpath, FileMode.Open);BinaryReader breader = new BinaryReader(fstream);img = breader.ReadBytes((int)fstream.Length);Clipboard.SetDataObject(Image.FromStream(fstream));txt1_sendinfo.Paste();imgflag = 1;}}//退出聊天室private void btn_Exit_Click(object sender, EventArgs e){if (btn_stop.Enabled != true){this.Close();Application.Exit();}else{MessageBox.Show("请先断开连接!");return;}}//取消发送private void btnRest_Click(object sender, EventArgs e){txt1_sendinfo.Clear();}//清屏private void btnClear_Click(object sender, EventArgs e){this.richTextBox1.Clear();}}}2.客户端using System;using System.Collections.Generic;using ponentModel;using System.Data;using System.Drawing;using System.Linq;using System.Text;using System.Windows.Forms;using ;using .Sockets;using System.Threading;using System.IO;namespace WindowsFormsApplication1{public partial class Form1 : Form{public Form1(){InitializeComponent();this.Init();tab2.Visible = true;tab3.Visible = false;tab1.Visible = false;}private void Init(){this.richTextBox1.Visible = false;this.txt2_send.Visible = false;}private void Init2(){this.richTextBox1.Visible = true;this.txt2_send.Visible = true;}//登录聊天室private void btnLog_Click(object sender, EventArgs e){if (txtIP.Text == "" || txtPort.Text == ""){MessageBox.Show("服务器信息不能为空!", "提示信息", MessageBoxButtons.OK, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button1);return;}if (txtName.Text == ""){MessageBox.Show("请输入您的呢称!", "提示信息", MessageBoxButtons.OK, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button1);return;}else{try{IPAddress ipadd = IPAddress.Parse(this.txtIP.Text);int port = Convert.ToInt32(this.txtPort.Text);userName = txtName.Text.ToString();tab1.Visible = true;this.Init2();tab3.Visible = true;this.btnImgFile.Enabled = false;this.Text = " " + userName + " " + DateTime.Now.ToString() + " " + DateTime.Now.DayOfWeek.ToString();richTextBox1.AppendText("System:"+ userName + " 已进入聊天室!<-"+ DateTime.Now.ToLongTimeString() + "->.....\r\n");string SerIp = txtIP.Text.ToString();string SerPort = txtPort.Text.ToString();lbSerIp.Text = " IP地址 :" + " " + SerIp + " ";lbSerPort.Text = " 端口号?:" + " " + SerPort;}catch (Exception){MessageBox.Show("您输入的服务器信息不合法,\n请重新输入!", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);}}}//重置服务器信息和昵称private void btnResent_Click(object sender, EventArgs e){txtIP.Clear();txtPort.Clear();txtName.Clear();}private OpenFileDialog openfiledialog = new OpenFileDialog();private SaveFileDialog savefiledialog = new SaveFileDialog();private byte[] img;//保存传图片时的字节数组private int imgflag = 0;private FileStream fstream;public delegate void UpdateMessage(string msg);public delegate void UpdateImg(Stream s);private Socket socket;private Thread thread;public string userName;//与服务器连接private void btn_req_Click(object sender, EventArgs e){try{IPAddress ip = IPAddress.Parse(this.txtIP.Text);IPEndPoint server = new IPEndPoint(ip, Int32.Parse(this.txtPort.Text));//创建客户端套接字socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);socket.Connect(server);//连接thread = new Thread(new ThreadStart(AcceptMessage));thread.Start();this.Text = " " + userName + " Taking....";richTextBox1.Clear();richTextBox1.AppendText("System:" + userName + " 连接到服务器!<-" + DateTime.Now.ToLongTimeString() + "->.....\r\n");btn_req.Enabled = false;btn_close.Enabled = true;btnImgFile.Enabled = true;}catch{richTextBox1.Clear();richTextBox1.AppendText("System:" + userName + " 未连接上服务器!<-" + DateTime.Now.ToLongTimeString() + "->.....\r\n");return;}}//接收后台接收消息public void AcceptMessage() //异步接收信息后台线程方法{while (true){try{if (this.socket == null || this.socket.Connected == false){richTextBox1.Clear();richTextBox1.AppendText("System:" + userName + "未连接上服务器!<-" + DateTime.Now.ToLongTimeString() + "->.....\r\n");break;}NetworkStream netStream = new NetworkStream(this.socket);//必须放在if后,this.socket可能没实例化//得到一条消息的长度byte[] dataSize = new byte[4];//前4字节代表后面字节总数,发送时骸已经处理过了try{netStream.Read(dataSize, 0, 4);}catch (Exception){}int size = System.BitConverter.ToInt32(dataSize, 0);//循环接收直到一条完整的消息全部读入到字节数组中byte[] message = new byte[size];int dataleft = size;int start = 0;while (dataleft > 0){int recv = netStream.Read(message, start, dataleft);start += recv;dataleft -= recv;}if (message[0] == 101)//101代表传输图片{MemoryStream ms = new MemoryStream(message, 1, message.Length - 1); richTextBox1.BeginInvoke(new UpdateImg(ViewImg), new object[] { ms });}else//默认进行普通传输{string Msg = System.Text.Encoding.Unicode.GetString(message, 1, message.Length - 1);richTextBox1.BeginInvoke(new UpdateMessage(ViewMessage), new object[] { Msg });}Thread.Sleep(100);}catch (.Sockets.SocketException ex){MessageBox.Show(userName + ":" + ex.Message);}}}//传输文件private void ViewMessage(string msg){richTextBox1.SelectionColor = Color.SteelBlue;richTextBox1.AppendText(msg + "\n");richTextBox1.SelectionStart = richTextBox1.Text.Length;//定位到最后,保持最新消息可见richTextBox1.Focus();txt2_send.Focus();}//接收图片信息private void ViewImg(Stream s){richTextBox1.SelectionStart = richTextBox1.Text.Length;richTextBox1.SelectionColor = Color.SteelBlue;richTextBox1.AppendText(userName + "接收图片<-"+ DateTime.Now.ToLongTimeString() + "->:\r\n");Clipboard.SetDataObject(Image.FromStream(s));//利用剪切板richTextBox1.Paste();richTextBox1.SelectionColor = Color.SteelBlue;richTextBox1.AppendText("\n");richTextBox1.SelectionStart = richTextBox1.Text.Length;richTextBox1.Focus();txt2_send.Focus();}//点击发送按钮private void btn_send_Click(object sender, EventArgs e){if (txt2_send.Text == ""){MessageBox.Show("请先输入内容!");txt2_send.Clear();txt2_send.Focus();return;}if (imgflag == 1)//imgflag的值在方法tnImgFile_Click中可能改变{//当传输图片时byte[] imgSize = new byte[4];//将32位整数值转换为字节数组imgSize = System.BitConverter.GetBytes(img.Length + 1);//后面一个标识数:101try{NetworkStream netStream = new NetworkStream(this.socket);netStream.Write(imgSize, 0, 4);netStream.WriteByte(101);//标识数netStream.Write(img, 0, img.Length);netStream.Flush();this.richTextBox1.SelectionColor = Color.LightCoral;this.richTextBox1.AppendText(userName + "<-"+ DateTime.Now.ToLongTimeString() + "->:\r\n");this.richTextBox1.SelectionStart = this.richTextBox1.Text.Length;Clipboard.SetDataObject(Image.FromStream(fstream));richTextBox1.Paste();richTextBox1.SelectionColor = Color.LightCoral;this.richTextBox1.AppendText("\n");fstream.Flush();fstream.Close();//此流必须在这里才可以消除txt2_send.Paste();this.richTextBox1.SelectionStart = this.richTextBox1.Text.Length;this.richTextBox1.Focus();this.txt2_send.Text = "";this.txt2_send.Focus();imgflag = 0;//复原return;//不执行后面的传输文本信息}catch (System.Exception ex){MessageBox.Show("服务器:" + ex.Message);}}//发送文本信息时this.richTextBox1.SelectionColor = Color.LightCoral;string str = userName + "<-" + DateTime.Now.ToLongTimeString() + "->:阰\r\n" + txt2_send.Text;int i = str.Length;if (i == 0){return;}else{//因为str为Unicode编码,每个字符占2个字节,所以实际字节数应为字符个数*2 i *= 2;}byte[] dataSize = new byte[4];//将32位整数值转换为字节数组dataSize = System.BitConverter.GetBytes(i + 1);//后面一个标识数:1 byte[] sendbytes = System.Text.Encoding.Unicode.GetBytes(str);try{NetworkStream netStream = new NetworkStream(this.socket);netStream.Write(dataSize, 0, 4);netStream.WriteByte(1);//标识数netStream.Write(sendbytes, 0, sendbytes.Length);netStream.Flush();richTextBox1.SelectionColor = Color.LightCoral;this.richTextBox1.AppendText(str + "\n");richTextBox1.SelectionStart = richTextBox1.Text.Length;richTextBox1.Focus();this.txt2_send.Rtf = "";txt2_send.Focus();}catch (System.Exception ex){MessageBox.Show(userName + ":" + ex.Message);}}//发送图片按钮private void btnImgFile_Click(object sender, EventArgs e){openfiledialog.Filter = "所有文件t(*.*)|*.*|位图文件t(*.bmp)|*.bmp|文件t (.jpg)|*.jpg|文件t(.gif)|*.gif";if (openfiledialog.ShowDialog() == DialogResult.OK){String strpath = openfiledialog.FileName;fstream = new FileStream(strpath, FileMode.Open);//此行和下一行是关键,得到文件字节数组BinaryReader breader = new BinaryReader(fstream);img = breader.ReadBytes((int)fstream.Length);//得到文件数组Clipboard.SetDataObject(Image.FromStream(fstream));txt2_send.Paste();imgflag = 1;}}//断开和服务器端连接óprivate void btn_close_Click(object sender, EventArgs e){socket.Close();thread.Abort();thread.Join(10);this.btn_req.Enabled = true;btn_close.Enabled = false;btnImgFile.Enabled = false;this.Text = " "+ userName + " "+ DateTime.Now.ToString() + " "+ DateTime.Now.DayOfWeek.ToString();this.richTextBox1.AppendText("System:" + userName + " 断开与服务器的连接!<-" + DateTime.Now.ToLongTimeString() + "->..... \r\n");}//退出聊天室private void btn_Exit_Click(object sender, EventArgs e){if (btn_close.Enabled != true){this.Close();Application.Exit();}else{MessageBox.Show("请先断开连接!");return;}}//取消发送private void btnRest_Click(object sender, EventArgs e) {txt2_send.Clear();}//清屏private void btnClear_Click(object sender, EventArgs e) {this.richTextBox1.Clear();}}}九.截图十.实验心得(注:可编辑下载,若有不当之处,请指正,谢谢!)。
计算机网络课程设计报告设计选题网络聊天室姓名马继鸣学号 0909090630完成时间 2012-1-12 一、需求分析聊天工具大多数由客户端程序和服务器程序外加服务器端,本程序采用客户机/服务器架构模式。
通过Java提供的Socket类来连接客户机和服务器并使客户机和服务器之间相互通信,由于聊天是多点对多点的而Java提供的多线程功能。
用多线程可完成多点对多点的聊天。
主要有两个应用程序,分别为服务器程序和客户端程序。
服务器应用程序主要用于消息转发,以及向所有用户发送系统消息等;客户端应用程序主要用于客户聊天记录的显示和信息输入。
采用Client/Server(C/S)体系结构,即客户机/服务器体系结构。
聊天服务器专门用于监控用户状态和转发消息,客户端负责接收消息的用户序列和消息文本发送到服务器。
该聊天系统实现群聊,用户登陆,退出聊天系统等功能。
二. 设计1.设计思想:课程设计中利用JAVA实现基于C/S模式的聊天程序。
聊天室共分为服务器端和客户端两部分,服务器端程序主要负责侦听客户发来的消息,客户端登录到服务器端才可以实现正常的聊天功能。
2.功能设计(1)服务器端的主要功能如下。
在特定端口上进行侦听,等待客户端连接。
用户可以配置服务端的侦听端口,默认端口为10000.当停止服务时,断开所有用户连接。
(2)客户端的主要功能如下。
连接到已经开启聊天服务的服务端。
当服务器端开启的话,用户可以随时登录与注销。
用户可以向所有人发送消息。
3.详细设计聊天室服务器端设计聊天室服务器中主要的功能文件的功能如下:MyButLis.java主要用于添加事件侦听和动作处理,具体是服务器按钮中的“终止”“发送”的处理。
public class MyButLis implements ActionListenerprivate MyServe server;private JTextField filed1;public void actionPerformed(ActionEvent e)MyChatSet.java服务器的线程队列,运行的方法,新增一个用户,则增加一个线程,并可以返回应答消息,给其余用户发送上下线信息,发送聊天信息(群聊私聊虽然已写,但是不知为何没有实现),发送用户列表。
简述网络聊天程序的原理
网络聊天程序的原理是基于网络通信技术,通过网络将用户之间的消息传递。
1. 客户端与服务器建立连接:客户端通过网络协议(如TCP/IP)与服务器建立连接,建立起双方之间的通信通道。
2. 用户登录或注册:用户使用客户端程序登录或注册,提供用户名和密码等信息,客户端将用户信息发送给服务器进行验证。
3. 接收和发送消息:用户通过客户端发送消息给服务器,服务器再将这些消息转发给其他在线的用户。
同时,服务器也会将其他用户发送的消息转发给当前用户。
4. 消息传递和存储:服务器会维护用户之间的关系和在线状态,并负责将消息传递给目标用户,并将消息进行存储。
5. 聊天记录存储:服务器通常会将聊天记录进行持久化存储,方便用户查询。
6. 退出聊天:当用户退出聊天时,客户端会发送请求告知服务器用户已经下线,服务器会更新用户的在线状态。
网络聊天程序的实现可以使用各种技术,如Socket编程、HTTP协议或
WebSockets等。
客户端可以是电脑上的软件应用,也可以是手机上的APP或浏览器中的网页。
服务器需要具备处理大量并发连接的能力,以及存储消息和用户信息的能力。
QQ 聊天程序的网络通信原理卢平(通信工程(2)班 E09680220)QQ的通信协议QQ的通信协议是一套基于二进制数据的自己开发的应用层网络协议。
其中使用一些公司的加密算法。
QQ基本通信协议支持udp和tcp两种基本协议方式。
两种方式的基本数据结构是一样的。
只是tcp包多了一个描述长度的头部。
QQ的通信原理QQ 聊天程序采用的是C/S 通信模式,即客户/服务模式,它把一个应用划分成功能不同的两个部分,分别在不同的计算机上运行,其中一个为服务端程序,用来响应和提供固定的服务,一个为客户端程序,用来向服务端提出请求和要求某种服务。
在数量关系上,通常有一对一的(即一个服务端程序和一个客户端程序之间通信),也有一对多的(即一个服务端程序和多个客户端程序之间通信),也有多对多的(即多个服务端程序和多个客户端程序之间通信)。
所谓服务端程序、客户端程序也是相对的概念,有时在一个程序中既有服务端又有客户端的功能。
QQ 聊天程序分成了两个程序,一个安装在腾讯公司的服务器上,我们称之为服务端程序,一个安装在QQ 用户的计算机上,我们称之为客户端程序。
在许多介绍网络通信编程的书籍中有关网络聊天的例子,当一个客户要与另一个客户聊天时,第一个客户先把聊天数据发送给服务器,然后服务器再把聊天数据转发给第二个客户,服务器好像一个中转站,这在客户数量比较少时,服务器还能承受,在客户数量比较多时,服务器肯定要瘫痪。
何况客户之间还要传送文件、语音聊天、视频聊天等等,为了减少服务器的压力,各客户端之间需要直接通信。
1。
在服务端和客户端之间(一对多)用于客户端程序登录,验证用户密码,获取其它在线好友信息等等。
2。
在客户端和客户端之间(多对多)用于在线好友间直接通信聊天。
此时每个客户端程序上既有实现服务端功能的部分,又有实现客户端功能的部分,前者用于接收聊天数据,后者用于发送聊天数据。
在用C/S 模式进行通信时,作为客户端在请求与服务端连接时需要知道服务端的IP 地址,腾讯公司的服务器具有固定的公网地址,这没有问题。
JAVA编写QQ聊天系统指导书一、QQ聊天系统简介1、模拟聊天系统包含两个方面,服务器端和客户端。
2、服务器端任务:建立一个ServerSocket,与客户端建立通信通道,不断侦听是否有客户端连接或者断开连接。
服务器端是一个信息转发中心,所有客户端的信息都传到服务器端,由服务器端根据要求分发信息。
3、客户端任务:建立一个Socket,与服务器端建立通信通道,向服务器端发送信息,并接收来自服务器的信息。
二、QQ聊天系统测试1、教师机新建一个java project,命名为QQchat,将“QQ聊天系统素材”下服务器端解压,将解压后的两个包com,client复制到QQchat/src下,运行Server.java。
弹出如图1-1所示图形界面,点击“开始”,将弹出如图1-2所示图形界面,服务器即打开。
图1-1 图1-22、指导学生新建一个java project,命名为QQchat,在“QQ聊天系统素材”下载客户端,将客户端下载解压,将解压后的两个包com,client复制到QQchat/src下,运行Client.java,将弹出如图1-3所示图形界面,输入服务器的ip,port,以及帐户名(自已姓名)登录,将弹出如图1-4所示图形界面。
点击如图1-5所示图形界面的下拉列表,在发送框中输入信息发送,就可以进行群聊或私聊。
图1-3 图1-4 图1-54、指导同学们下载服务器端,同学们轮流运行服务器程序,其它同学通过某个同学的服务器程序进行聊天。
不同的服务器以IP地址区别。
需要提醒学生注意的是:只有登录同一个服务器的客户端才能相互聊天,测试时服务器端只能有一个,学生们需要轮流做服务器,而客户端可以有多个,没有限制。
三、QQ聊天系统设计与实现操作步骤。
任务一目的:通过网络编程,让同学们与老师互通字节信息。
老师做服务器,学生做客户端。
具体操作步骤:教师与学生都新建一个java project,命名如zhangsanQQchat(以本人姓名+QQchat为文件名),在src下新建一个other包,教师在other包下新建Server.java 类并运行。
QQ工作原理--开发IM即时通讯工具IM即时通讯工具在现代社会已经成为我们日常交流的重要工具之一。
其中,QQ作为中国最著名的即时通讯软件之一,拥有大量的用户群体。
本文将从服务器架构、消息传输、数据加密等方面介绍QQ的工作原理。
一、服务器架构QQ的服务器架构是其高效运行的基础。
QQ采用了分布式服务器架构,即将服务划分为多个模块,并将这些模块部署在不同的服务器上。
这样一来,不同服务器之间可以并行处理用户请求,提高了系统的并发能力和处理速度。
1. 登录服务器登录服务器是QQ的核心模块之一,负责处理用户的登录请求。
当用户启动QQ客户端并输入正确的账号密码后,登录服务器会进行身份验证,验证通过后,将用户所在的服务器信息返回给客户端。
这样,用户就可以和其他在线用户建立连接并进行即时通讯。
2. 聊天服务器聊天服务器负责处理用户间的消息传输。
当用户发送消息时,消息将首先发送到聊天服务器,服务器再将消息转发给目标用户。
这种方式可以实现即时消息的实时传输,并且保证消息的可靠性。
3. 存储服务器存储服务器用于存储用户的个人资料、聊天记录等数据。
用户的个人资料包括账号信息、好友列表等,而聊天记录则包括用户之间的聊天内容、发送时间等信息。
存储服务器的设计可以保证用户数据的安全性和可靠性。
二、消息传输QQ使用了TCP/IP协议进行消息传输。
TCP协议可保障消息的可靠传输,保证消息不会丢失或损坏。
而IP协议则负责寻址和路由,确保消息能够准确地发送到目标用户。
在消息传输的过程中,QQ采用了类似于邮局的方式。
发送消息的用户相当于写信人,聊天服务器相当于邮局,接收消息的用户相当于收信人。
发送消息时,源用户将消息发送给聊天服务器,服务器再将消息转发给目标用户。
这样的设计可以确保消息能够准确地传递到目标用户手中。
三、数据加密为了保障用户的隐私和信息安全,QQ采用了数据加密技术。
在用户登录时,QQ客户端会将用户的密码进行加密处理后再发送给服务器。