利用TCP协议通过Socket编写的网络聊天工具1-客户端
面向对象课程大作业要求写一个面向对象设计的工程,所以我选择了网络聊天。
整个项目源码下载地址:http://download.csdn.net/detail/weixingstudio/4301232
具体的分析以后给出,先给出部分代码实现。
这里的实现只有客户端,服务器端下一节给出。
登录窗口的代码:
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using UtilityClass; using System.Net; using System.Net.Sockets; using System.Collections.Specialized; namespace Client { public partial class Login : Form { public Login() { InitializeComponent(); } private void button_cancel_Click(object sender, EventArgs e) { this.Close(); } private void button_OK_Click(object sender, EventArgs e) { VerifyUserInfo verify = new VerifyUserInfo(); string userName = textBox1.Text.Trim(); string serverIP = textBox2.Text.Trim(); string serverPort = textBox3.Text.Trim(); if (!verify.VerifyUserName(userName)) { MessageBox.Show("请重新填写用户名!","提示"); textBox1.Focus(); } else { if (!verify.VerifyServerIP(serverIP)) { MessageBox.Show("请重新填写服务器IP!", "提示"); textBox2.Focus(); } else { if (!verify.VerifyServerPort(serverPort)) { MessageBox.Show("请重新填写服务器端口!", "提示"); textBox3.Focus(); } else { // 打开聊天窗口 //MessageBox.Show("Good", "提示"); try { int serverPort_int=int.Parse(serverPort); ServerConfig serverConfig = new ServerConfig(serverIP, serverPort_int); IPAddress serverIPAddress = IPAddress.Parse(serverConfig.ServerIP); TcpClient client = new TcpClient(); client.Connect(serverIPAddress, serverConfig.ServerPort); if (client==null) { MessageBox.Show("连接服务器失败,请重新填写服务器数据或者查看服务器运行状态!", "提示"); textBox1.Focus(); } else { // 连接成功以后的操作 NetworkStream clientNetWorkStream = client.GetStream(); // 发送用户名 byte[] bytes2beSend=Command.EncodeCommand(userName); clientNetWorkStream.Write(bytes2beSend, 0, bytes2beSend.Length); byte[] receiveBuffer=new byte[serverConfig.MaxBuffer]; clientNetWorkStream.Read(receiveBuffer, 0, receiveBuffer.Length); string connResult = Command.DecodeCommand(receiveBuffer); if (connResult==Command.RedundantUserName) { MessageBox.Show("重复的用户名,请重新填写用户名。", "提示"); } else if (connResult==Command.ExceedMaxAllowedNumber) { MessageBox.Show("超出了服务器最多允许的连接数量,请稍后连接!", "提示"); } else if (connResult==Command.ConnectConfirm) { //// 请求用户列表 //// 开始先请求一个在线用户列表 //byte[] cmd = new byte[serverConfig.MaxBuffer]; //cmd = Command.EncodeCommand(Command.RequestOnlineUser); //clientNetWorkStream.Write(cmd, 0, cmd.Length); //// 读取在线用户列表 //clientNetWorkStream.Read(cmd, 0, cmd.Length); //StringCollection sc = Command.DeserializeOnlineUser(cmd); // 打开聊天窗口 MainChatFrm mainChat = new MainChatFrm(userName,serverConfig,clientNetWorkStream); // 将数据流传递给另外一个窗口 mainChat.Owner = this; this.Hide(); mainChat.Show(); } } } catch (System.Exception ex) { MessageBox.Show("出错了!远程服务器没有响应。连接服务器失败,请重新填写服务器数据或者查看服务器运行状态!", "提示"); } } } } } } }
主聊天窗口的代码:
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using UtilityClass; using System.Net.Sockets; using System.Threading; using System.Runtime.InteropServices; using System.Collections.Specialized; namespace Client { public partial class MainChatFrm : Form { Thread receiveMegThread; ServerConfig serverConfig; NetworkStream networkStream; string userName; private bool isDisconnected = false; private delegate void showMessage(string s); private delegate void addOnlineUser(string s); public MainChatFrm() { InitializeComponent(); } public MainChatFrm(string name, ServerConfig config, NetworkStream ns) { InitializeComponent(); this.listBox_onlineuser.Items.Clear(); this.userName = name; this.serverConfig = config; this.networkStream = ns; this.label_username.Text += userName; this.label_serverIP.Text += serverConfig.ServerIP + ":" + serverConfig.ServerPort; this.richTextBox1.Text += "你好 " + userName + ",欢迎来到微星聊天室! " + DateTime.Now + "\n"; try { // 开启接收消息的线程 receiveMegThread = new Thread(new ThreadStart(ReceiveMessage)); receiveMegThread.IsBackground = true; receiveMegThread.Start(); Thread.Sleep(100); } catch (System.Exception ex) { // } } /// <summary> /// 接收消息处理线程函数 /// </summary> private void ReceiveMessage() { try { while (true) { byte[] receiveBuffer=new byte[serverConfig.MaxBuffer]; networkStream.Read(receiveBuffer, 0, receiveBuffer.Length); string cmd_from_server = Command.DecodeCommand(receiveBuffer); switch (cmd_from_server) { // 服务器通知有用户上线 case Command.SomeoneConnected: { // 获取用户名 byte[] cmd=new byte[serverConfig.MaxBuffer]; networkStream.Read(cmd, 0, cmd.Length); string name = Command.DecodeCommand(cmd); if (name!=userName) { // 线程安全的添加数据到RichTextBox AddText2RTB("用户:" + name + " 上线了!" + " " + DateTime.Now); } else { // nothing } // 请求最新的用户列表 cmd = Command.EncodeCommand(Command.RequestOnlineUser); // 发送请求在线用户列表命令 networkStream.Write(cmd, 0, cmd.Length); break; } // 服务器发送用户列表 case Command.SendOnlinUserList: { // 接收数据 networkStream.Read(receiveBuffer, 0, receiveBuffer.Length); StringCollection sc = Command.DeserializeOnlineUser(receiveBuffer); ClearOnlineUserList(); ClearComboList(); foreach (string s in sc) { // 线程安全的添加数据 AddOnlineUserList(s); } break; } // 有人离开 case Command.SomeoneLeave: { byte[] cmd=new byte[serverConfig.MaxBuffer]; networkStream.Read(cmd, 0, cmd.Length); string name = Command.DecodeCommand(cmd); AddText2RTB("用户:" + name + " 离开了系统." + DateTime.Now); // 线程安全的移除下线的用户 Action<object> call = delegate(object s) { this.listBox_onlineuser.Items.Remove(s); this.comboBox_selectUser.Items.Remove(s); }; this.listBox_onlineuser.Invoke(call, name); break; } // 有广播消息 case Command.BroadcastAll: { // 获取广播消息的用户名 byte[] cmd=new byte[serverConfig.MaxBuffer]; networkStream.Read(cmd, 0, cmd.Length); string name = Command.DecodeCommand(cmd); AddText2RTB("用户:" + name + "在" + DateTime.Now + "对大家说:"); byte[] msg=new byte[serverConfig.MaxBuffer]; networkStream.Read(msg, 0, msg.Length); string message = Command.DecodeCommand(msg); AddText2RTB(message); break; } // 对这个用户单独发送数据 case Command.SendMessage2One: { byte[] cmd = new byte[serverConfig.MaxBuffer]; networkStream.Read(cmd, 0, cmd.Length); string name_from = Command.DecodeCommand(cmd); // Thread.Sleep(20); networkStream.Read(cmd, 0, cmd.Length); string message = Command.DecodeCommand(cmd); AddText2RTB("用户:" + name_from + "在" + DateTime.Now + "对你悄悄的说:"); AddText2RTB(message); break; } // 请求抖动 case Command.VibrateOne: { byte[] cmd = new byte[serverConfig.MaxBuffer]; networkStream.Read(cmd, 0, cmd.Length); string name_from = Command.DecodeCommand(cmd); AddText2RTB("用户:" + name_from + "在" + DateTime.Now + "给您发送了一个抖动"); Vibrate(); break; } case Command.VibrateAll: { byte[] cmd = new byte[serverConfig.MaxBuffer]; networkStream.Read(cmd, 0, cmd.Length); string name_from = Command.DecodeCommand(cmd); AddText2RTB("用户:" + name_from + "在" + DateTime.Now + "给所有人发送了一个抖动"); Vibrate(); break; } case Command.ServerShutdown: { AddText2RTB("服务器已经关闭,请退出程序,重新连接服务器。"); this.networkStream.Close(); networkStream=null; this.button_send.Enabled = false; break; } default: { break; } } } } catch (System.Exception ex) { // 服务器连接失败,清理连接 if (networkStream!=null) { MessageBox.Show("服务器连接失败!"); networkStream.Close(); networkStream = null; } } } private void ClearOnlineUserList() { Action call = delegate() { this.listBox_onlineuser.Items.Clear(); }; this.listBox_onlineuser.Invoke(call); } private void ClearComboList() { Action call = delegate() { this.comboBox_selectUser.Items.Clear(); }; this.comboBox_selectUser.Invoke(call); } private void AddOnlineUserList(string user) { addOnlineUser call = delegate(string s) { this.listBox_onlineuser.Items.Add(s); this.comboBox_selectUser.Items.Add(s); }; this.listBox_onlineuser.Invoke(call,user); } //private void fromClosed(object sender, FormClosedEventArgs e) //{ // DisConnectWithServer(); // this.Owner.Close(); // this.Close(); //} private void button_close_Click(object sender, EventArgs e) { if (networkStream != null) { DialogResult ret; ret = MessageBox.Show("确定与服务器断开连接吗?", "退出", MessageBoxButtons.OKCancel, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2); if (ret == DialogResult.OK) { try { isDisconnected = true; // 向服务器发送离线请求 byte[] cmd = Command.EncodeCommand(Command.DisConnect); networkStream.Write(cmd, 0, cmd.Length); if (receiveMegThread != null) { receiveMegThread.Abort(); } if (networkStream != null) { // 关闭网络流 networkStream.Close(); networkStream.Dispose(); } this.Owner.Close(); this.Close(); } catch (System.Exception ex) { } } } else { this.Owner.Close(); this.Close(); } } /// <summary> /// 与服务器断开连接 /// </summary> private void DisConnectWithServer() { } [DllImport("user32.dll")] public static extern bool FlashWindow(IntPtr hWnd, bool bInvert); /// <summary> /// 给用户发送抖动 /// /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void pictureBox1_Click(object sender, EventArgs e) { if (radioButton_all.Checked) { //AddText2RTB("禁止对所有用户发送抖动!"); // 发送命令 byte[] cmd = Command.EncodeCommand(Command.VibrateAll); networkStream.Write(cmd, 0, cmd.Length); Thread.Sleep(20); AddText2RTB("您给所有人发送了一个抖动"); Vibrate(); } else if (radioButton_one.Checked) { // 给当个用户发送抖动 if (this.comboBox_selectUser.SelectedItem==null) { MessageBox.Show("请选择一个私聊用户"); } else { string name_private = comboBox_selectUser.SelectedItem.ToString(); if (name_private == userName) { MessageBox.Show("您不能给自己发送抖动!"); } else { // 发送命令 byte[] cmd=Command.EncodeCommand(Command.VibrateOne); networkStream.Write(cmd, 0, cmd.Length); Thread.Sleep(20); // 发送抖动用户 cmd = Command.EncodeCommand(name_private); networkStream.Write(cmd, 0, cmd.Length); Thread.Sleep(20); Vibrate(); } } } } private void Vibrate() { if (this.WindowState == FormWindowState.Minimized) { FlashWindow(this.Handle, true); } Nudge(); } /// <summary> /// 产生闪屏振动效果 /// </summary> private void Nudge() { if (this.WindowState == FormWindowState.Minimized) { this.WindowState = FormWindowState.Normal; } int i = 0; Point _old = this.Location; Point _new1 = new Point(_old.X + 2, _old.Y + 2); Point _new2 = new Point(_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; } private void chatFrm_close(object sender, FormClosedEventArgs e) { if (!isDisconnected) { try { if (networkStream != null) { DialogResult ret; ret = MessageBox.Show("确定与服务器断开连接吗?", "退出", MessageBoxButtons.OKCancel, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2); if (ret == DialogResult.OK) { isDisconnected = true; // 向服务器发送离线请求 byte[] cmd = Command.EncodeCommand(Command.DisConnect); networkStream.Write(cmd, 0, cmd.Length); if (receiveMegThread != null) { receiveMegThread.Abort(); } if (networkStream != null) { // 关闭网络流 networkStream.Close(); networkStream.Dispose(); networkStream = null; } this.Owner.Close(); this.Close(); } } else { isDisconnected = true; this.Owner.Close(); this.Close(); } } catch (System.Exception ex) { // } } } private void AddText2RTB(string msg) { if (this.richTextBox1.InvokeRequired) { showMessage call = delegate(string s) { this.richTextBox1.Text += s + "\n"; }; this.richTextBox1.Invoke(call, msg); } else { this.richTextBox1.Text += msg + "\n"; } } /// <summary> /// 发送用户消息 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void button_send_Click(object sender, EventArgs e) { string messsage = this.richTextBox2.Text; if (Command.VerifyMessage(messsage)) { // 验证将要发送的消息正确 if (radioButton_all.Checked) { // 给所有人发送消息 // 给服务器发送命令 byte[] cmd = Command.EncodeCommand(Command.BroadcastAll); networkStream.Write(cmd, 0, cmd.Length); Thread.Sleep(50); // 发送要传送的数据 cmd = Command.EncodeCommand(messsage); networkStream.Write(cmd, 0, cmd.Length); AddText2RTB("你" + "在 " + DateTime.Now + " 对大家说:"); AddText2RTB(messsage); this.richTextBox2.Text = ""; this.richTextBox2.Focus(); } else if (radioButton_one.Checked) { // 给单个人发送消息 try { if (comboBox_selectUser.SelectedItem==null) { MessageBox.Show("请选择一个私聊用户"); } string name_private = comboBox_selectUser.SelectedItem.ToString(); if (name_private == userName) { MessageBox.Show("您不能和自己私聊!"); this.richTextBox2.Text = ""; this.richTextBox2.Focus(); } else { // 发送命令 byte[] cmd = Command.EncodeCommand(Command.SendMessage2One); networkStream.Write(cmd, 0, cmd.Length); Thread.Sleep(50); // 发送对象名 cmd = Command.EncodeCommand(name_private); networkStream.Write(cmd, 0, cmd.Length); Thread.Sleep(50); // 发送数据 cmd = Command.EncodeCommand(messsage); networkStream.Write(cmd, 0, cmd.Length); AddText2RTB("你" + "在 " + DateTime.Now + " 对 " + name_private + "说:"); AddText2RTB(messsage); this.richTextBox2.Text = ""; this.richTextBox2.Focus(); } } catch (System.Exception ex) { // } } } else { this.richTextBox2.Text = ""; this.richTextBox2.Focus(); AddText2RTB("请输入正确的消息然后在发送!!!" + DateTime.Now); } } /// <summary> /// 清除数据 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void button_clear_Click(object sender, EventArgs e) { this.richTextBox2.Text = ""; this.richTextBox2.Focus(); } private void richTextBox1_TextChanged(object sender, EventArgs e) { this.richTextBox1.SelectionStart = this.richTextBox1.TextLength; this.richTextBox1.ScrollToCaret(); if (this.WindowState == FormWindowState.Minimized) { FlashWindow(this.Handle, true); } } } }
其中封装了两个在服务器端和客户端工程中都需要使用的配置类和命令类,下一节给出。
相关推荐
无人机最强算法源码,易于部署和学习交流使用
Node.js,简称Node,是一个开源且跨平台的JavaScript运行时环境,它允许在浏览器外运行JavaScript代码。Node.js于2009年由Ryan Dahl创立,旨在创建高性能的Web服务器和网络应用程序。它基于Google Chrome的V8 JavaScript引擎,可以在Windows、Linux、Unix、Mac OS X等操作系统上运行。 Node.js的特点之一是事件驱动和非阻塞I/O模型,这使得它非常适合处理大量并发连接,从而在构建实时应用程序如在线游戏、聊天应用以及实时通讯服务时表现卓越。此外,Node.js使用了模块化的架构,通过npm(Node package manager,Node包管理器),社区成员可以共享和复用代码,极大地促进了Node.js生态系统的发展和扩张。 Node.js不仅用于服务器端开发。随着技术的发展,它也被用于构建工具链、开发桌面应用程序、物联网设备等。Node.js能够处理文件系统、操作数据库、处理网络请求等,因此,开发者可以用JavaScript编写全栈应用程序,这一点大大提高了开发效率和便捷性。 在实践中,许多大型企业和组织已经采用Node.js作为其Web应用程序的开发平台,如Netflix、PayPal和Walmart等。它们利用Node.js提高了应用性能,简化了开发流程,并且能更快地响应市场需求。
此数据集主要是一个跟酒店类型有关的数据集,源于kaggle网站上的Guatemalas_Travel数据集,因设计所需,本人对原来的数据集进行了必要的修改。
3D相册.zip
数据来源:中国统计NJ-2023版
3dmax空对象清除器,在场景中找到空对象,向你显示这些对象的列表,并允许你从场景中删除它们。
Node.js,简称Node,是一个开源且跨平台的JavaScript运行时环境,它允许在浏览器外运行JavaScript代码。Node.js于2009年由Ryan Dahl创立,旨在创建高性能的Web服务器和网络应用程序。它基于Google Chrome的V8 JavaScript引擎,可以在Windows、Linux、Unix、Mac OS X等操作系统上运行。 Node.js的特点之一是事件驱动和非阻塞I/O模型,这使得它非常适合处理大量并发连接,从而在构建实时应用程序如在线游戏、聊天应用以及实时通讯服务时表现卓越。此外,Node.js使用了模块化的架构,通过npm(Node package manager,Node包管理器),社区成员可以共享和复用代码,极大地促进了Node.js生态系统的发展和扩张。 Node.js不仅用于服务器端开发。随着技术的发展,它也被用于构建工具链、开发桌面应用程序、物联网设备等。Node.js能够处理文件系统、操作数据库、处理网络请求等,因此,开发者可以用JavaScript编写全栈应用程序,这一点大大提高了开发效率和便捷性。 在实践中,许多大型企业和组织已经采用Node.js作为其Web应用程序的开发平台,如Netflix、PayPal和Walmart等。它们利用Node.js提高了应用性能,简化了开发流程,并且能更快地响应市场需求。
数据来源:中国统计NJ-2023版
数据要素资产化与数据资产入表路线框架总体规划方案.pptx
施耐德电气 8100C 8200C 8300C 用户手册
无人机最强算法源码,易于部署和学习交流使用
员工培训方案gl.ppt
旅行商问题
小米扫地机器人工程源码程序STM32103 freeRTOS设计源代码,某米早起的扫地机器人的源码,使用的是STM32开发,freeRTOS系统,包含完整的工程源码,可以做为你的学习设计参考。 HARDWARE文件夹 硬件初始化源文件 application_Robot 机器人行为相关的文件 application_Share 机器人共享相关的文件(一般为算法) application_Motor 机器人电机应用相关文件 application_Key 机器人按键应用相关文件 application_Led 机器人LED应用相关文件 application_Led 机器人adc获取与处理应用相关文件 application_PowerChip 机器人电池管理芯片与充电应用相关文件 application_Bmi160 机器人BMI160 陀螺仪芯片 应用相关文件 application_Drop 机器人掉落传感器应用相关文件 application_UltraSonic 机器人超声波传感器应用相关文件 appl
39黎秋菊.ipynb
Node.js,简称Node,是一个开源且跨平台的JavaScript运行时环境,它允许在浏览器外运行JavaScript代码。Node.js于2009年由Ryan Dahl创立,旨在创建高性能的Web服务器和网络应用程序。它基于Google Chrome的V8 JavaScript引擎,可以在Windows、Linux、Unix、Mac OS X等操作系统上运行。 Node.js的特点之一是事件驱动和非阻塞I/O模型,这使得它非常适合处理大量并发连接,从而在构建实时应用程序如在线游戏、聊天应用以及实时通讯服务时表现卓越。此外,Node.js使用了模块化的架构,通过npm(Node package manager,Node包管理器),社区成员可以共享和复用代码,极大地促进了Node.js生态系统的发展和扩张。 Node.js不仅用于服务器端开发。随着技术的发展,它也被用于构建工具链、开发桌面应用程序、物联网设备等。Node.js能够处理文件系统、操作数据库、处理网络请求等,因此,开发者可以用JavaScript编写全栈应用程序,这一点大大提高了开发效率和便捷性。 在实践中,许多大型企业和组织已经采用Node.js作为其Web应用程序的开发平台,如Netflix、PayPal和Walmart等。它们利用Node.js提高了应用性能,简化了开发流程,并且能更快地响应市场需求。
模板描述:域名注册查询 微信小程序。域名注册查询的微信小程序页面源码是使用微信WEB开发者工具开发,亲测可直接运行。该程序从设计上满足了相关应用服务的设计要求,是一款非常值得学习简介的DEMO小程序源码。
无人机最强算法源码,易于部署和学习交流使用
DCS 400 手册
Node.js,简称Node,是一个开源且跨平台的JavaScript运行时环境,它允许在浏览器外运行JavaScript代码。Node.js于2009年由Ryan Dahl创立,旨在创建高性能的Web服务器和网络应用程序。它基于Google Chrome的V8 JavaScript引擎,可以在Windows、Linux、Unix、Mac OS X等操作系统上运行。 Node.js的特点之一是事件驱动和非阻塞I/O模型,这使得它非常适合处理大量并发连接,从而在构建实时应用程序如在线游戏、聊天应用以及实时通讯服务时表现卓越。此外,Node.js使用了模块化的架构,通过npm(Node package manager,Node包管理器),社区成员可以共享和复用代码,极大地促进了Node.js生态系统的发展和扩张。 Node.js不仅用于服务器端开发。随着技术的发展,它也被用于构建工具链、开发桌面应用程序、物联网设备等。Node.js能够处理文件系统、操作数据库、处理网络请求等,因此,开发者可以用JavaScript编写全栈应用程序,这一点大大提高了开发效率和便捷性。 在实践中,许多大型企业和组织已经采用Node.js作为其Web应用程序的开发平台,如Netflix、PayPal和Walmart等。它们利用Node.js提高了应用性能,简化了开发流程,并且能更快地响应市场需求。