热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

学习Socket编写的聊天室小程序

学习Socket编写的聊天室小程序1.前言在学习Socket之前,先来学习点网络相关的知识吧,自己学习过程中的一些总结,Socket是一门

学习Socket编写的聊天室小程序

1.前言

在学习Socket之前,先来学习点网络相关的知识吧,自己学习过程中的一些总结,Socket是一门很高深的学问,本文只是Socket一些最基础的东西,大神请自觉绕路。

传输协议

TCP:Transmission Control Protocol 传输控制协议TCP是一种面向连接(连接导向)的、可靠的、基于字节流的运输层(Transport layer)通信协议。

特点:

面向连接的协议,数据传输必须要建立连接,所以在TCP中需要连接时间。

传输数据大小限制,一旦连接建立,双方可以按统一的格式传输大的数据。

一个可靠的协议,确保接收方完全正确地获取发送方所发送的全部数据。

说到TCP就不得不说经典的三次握手。

在TCP/IP协议中,TCP协议通过三次握手建立一个可靠的连接

第一次握手:客户端尝试连接服务器,向服务器发送syn包(同步序列编号Synchronize Sequence Numbers),syn=j,客户端进入SYN_SEND状态等待服务器确认

第二次握手:服务器接收客户端syn包并确认(ack=j+1),同时向客户端发送一个SYN包(syn=k),即SYN+ACK包,此时服务器进入SYN_RECV状态

第三次握手:第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手

学习Socket编写的聊天室小程序

UDP: User Datagram Protocol的简称, 中文名是用户数据包协议,是 OSI 参考模型中一种无连接的传输层协议,提供面向事务的简单不可靠信息传送服务。

特点:

每个数据报中都给出了完整的地址信息,因此无需要建立发送方和接收方的连接。

UDP传输数据时是有大小限制的,每个被传输的数据报必须限定在64KB之内。

UDP是一个不可靠的协议,发送方所发送的数据报并不一定以相同的次序到达接收方。

学习Socket编写的聊天室小程序

TCP协议:就好比两个电话机 通过电话线进行数据交互的格式约定

HTTP协议:就好比两个人 通过电话机 说话的语法。

(1)公认端口(WellKnownPorts):从0到1023,它们紧密绑定(binding)于一些服务。通常这些端口的通讯明确表明了某种服务的协议。例如:80端口实际上总是HTTP通讯。

(2)注册端口(RegisteredPorts):从1024到49151。它们松散地绑定于一些服务。也就是说有许多服务绑定于这些端口,这些端口同样用于许多其它目的。例如:许多系统处理动态端口从1024左右开始。

(3)动态和/或私有端口(Dynamicand/orPrivatePorts):从49152到65535。理论上,不应为服务分配这些端口。实际上,机器通常从1024起分配动态端口。

OSI网络7层模型

学习Socket编写的聊天室小程序

TCP/IP(Transmission Control Protocol/Internet Protocol)即传输控制协议/网间协议,是一个工业标准的协议集,它是为广域网(WANs)设计的。

UDP(User Data Protocol,用户数据报协议)是与TCP相对应的协议。它是属于TCP/IP协议族中的一种。

应用层 (Application):应用层是个很广泛的概念,有一些基本相同的系统级 TCP/IP 应用以及应用协议,也有许多的企业商业应用和互联网应用。

传输层 (Transport):传输层包括 UDP 和 TCP,UDP 几乎不对报文进行检查,而 TCP 提供传输保证。

网络层 (Network):网络层协议由一系列协议组成,包括 ICMP、IGMP、RIP、OSPF、IP(v4,v6) 等。

链路层 (Link):又称为物理数据网络接口层,负责报文传输。

学习Socket编写的聊天室小程序

IP地址

每台联网的电脑都有一个唯一的IP地址。

长度32位,分为四段,每段8位,用十进制数字表示,每段范围 0 ~ 255

特殊IP:127.0.0.1 用户本地网卡测试

版本:V4(32位) 和 V6(128位,分为8段,每段16位)

端口

在网络上有很多电脑,这些电脑一般运行了多个网络程序。每种网络程序都打开一个Socket,并绑定到一个端口上,不同的端口对应于不同的网络程序。

常用端口:21 FTP ,25 SMTP ,110 POP3 ,80 HTTP , 443 HTTPS

有两种常用Socket类型:

流式Socket(STREAM):

是一种面向连接的Socket,针对于面向连接的TCP服务应用,安全,但是效率低

数据报式Socket(DATAGRAM):

是一种无连接的Socket,对应于无连接的UDP服务应用.不安全(丢失,顺序混乱,在接收端要分析重排及要求重发),但效率高.

说了那么多,让我们来看看socket在网络7层协议中的位置。如下图所示

学习Socket编写的聊天室小程序

2.聊天室原理

学习Socket编写的聊天室小程序

Socket 流式(服务器端和客户端

服务器端的Socket(至少需要两个)

一个负责接收客户端连接请求(但不负责与客户端通信)

每成功接收到一个客户端的连接便在服务端产生一个对应的负责通信的Socket

在接收到客户端连接时创建.

为每个连接成功的客户端请求在服务端都创建一个对应的Socket(负责和客户端通信).

客户端的Socket

客户端Socket

必须指定要连接的服务端IP地址和端口。

通过创建一个Socket对象来初始化一个到服务器端的TCP连接

Socket的通讯过程

服务器端:

申请一个socket

绑定到一个IP地址和一个端口上

开启侦听,等待接授连接

客户端:

申请一个socket

连接服务器(指明IP地址和端口号)

l服务器端接到连接请求后,产生一个新的socket(端口大于1024)与客户端建立连接并进行通讯,原监听socket继续监听。

Socket常用的一些类和方法

IPAddress类:包含了一个IP地址

IPEndPoint类:包含了一对IP地址和端口号

Socket : 创建一个Socket

Bind: 绑定一个本地的IP和端口号(IPEndPoint)

Listen: 让Socket侦听传入的连接尝试,并指定侦听队列容量

Connect: 初始化与另一个Socket的连接

Accept: 接收连接并返回一个新的socket

Send: 输出数据到Socket

Receive: 从Socket中读取数据

Close: 关闭Socket (销毁连接)

学习Socket编写的聊天室小程序

3.聊天室代码

服务器端代码:

using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;namespace Server
{using System.Net.Sockets;using System.Net;using System.Threading;public partial class Form1 : Form{

public Form1{InitializeComponent;TextBox.CheckForIllegalCrossThreadCalls = false;}

//服务端 监听套接字Socket socketWatch = null;//服务端 监听线程Thread threadWatch = null;//字典集合:保存 通信套接字Dictionary dictCon = new Dictionary;

private void btnStartListen_Click(object sender, EventArgs e){try{//1.创建监听套接字 使用 ip4协议,流式传输,TCP连接socketWatch = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);//2.绑定端口//2.1获取网络节点对象IPAddress address = IPAddress.Parse(txtIP.Text);IPEndPoint endPoint = new IPEndPoint(address, int.Parse(txtPort.Text));//2.2绑定端口(其实内部 就向系统的 端口表中 注册 了一个端口,并指定了当前程序句柄)socketWatch.Bind(endPoint);//2.3设置监听队列socketWatch.Listen(10);//2.4开始监听,调用监听线程 执行 监听套接字的 监听方法threadWatch = new Thread(WatchConnecting);threadWatch.IsBackground = true;threadWatch.Start;ShowMsg("枫伶忆,服务器启动啦!");}catch (Exception ex){MessageBox.Show(ex.Message);throw;}}

void WatchConnecting{//2.4开始监听:此方法会阻断当前线程,直到有 其它程序 连接过来,才执行完毕Socket sokMsg = socketWatch.Accept;//将当前连接成功的 【与客户端通信的套接字】 的 标识 保存起来,并显示到 列表中//将 远程客户端的 ip和端口 字符串 存入 列表this.lbOnline.Items.Add(sokMsg.RemoteEndPoint.ToString);//将 服务端的通信套接字 存入 字典集合dictCon.Add(sokMsg.RemoteEndPoint.ToString, sokMsg);ShowMsg("有客户端连接了!");//2.5创建 通信线程Thread thrMsg = new Thread(ReceiveMsg);thrMsg.IsBackground = true;thrMsg.Start(sokMsg);}

void ReceiveMsg(object obj){try{Socket sokMsg = obj as Socket;//3.通信套接字 监听 客户端的 消息//3.1创建 消息缓存区byte arrMsg = new byte[1024 * 1024 * 1];while (isReceive){//3.2接收客户端的消息 并存入 缓存区,注意:Receive方法也会阻断当前的线程sokMsg.Receive(arrMsg);//3.3将接收到的消息 转成 字符串string strMsg = System.Text.Encoding.UTF8.GetString(arrMsg);//3.4将消息 显示到 文本框ShowMsg(strMsg);}}catch (Exception ex){MessageBox.Show(ex.Message);throw;}}

void ShowMsg(string strmsg){this.txtShow.AppendText(strmsg + "\r\n");}

private void btnSend_Click_1(object sender, EventArgs e){string strClient = this.lbOnline.Text;if (string.IsNullOrEmpty(strClient)){MessageBox.Show("请选择你要发送消息的客户端");return;}if (dictCon.ContainsKey(strClient)){string strMsg = this.txtInput.Text.Trim;ShowMsg("\r\n向客户端【" + strClient + "】说:" + strMsg);//使用 指定的 通信套接字 将 字符串 发送到 指定的客户端byte arrMsg = System.Text.Encoding.UTF8.GetBytes(strMsg);dictCon[strClient].Send(arrMsg);}this.txtInput.Text = "";}

}}

客户端代码:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;namespace Client
{using System.Net.Sockets;using System.Net;using System.Threading;public partial class Form1 : Form{

public Form1{InitializeComponent;TextBox.CheckForIllegalCrossThreadCalls = false;}

//客户端 通信套接字Socket socketMsg = null;//客户端 通信线程Thread threadMsg = null;bool isRec = true;//标记任务

private void btnConnect_Click(object sender, EventArgs e){try{//1.创建监听套接字 使用 ip4协议,流式传输,TCP连接socketMsg = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);//2.获取要连接的服务端 节点//2.1获取网络节点对象IPAddress address = IPAddress.Parse(txtIP.Text);IPEndPoint endPoint = new IPEndPoint(address, int.Parse(txtPort.Text));//3.向服务端 发送链接请求socketMsg.Connect(endPoint);ShowMsg("连接服务器成功~~!");//4.开启通信线程threadMsg = new Thread(RecevieMsg);threadMsg.IsBackground = true;threadMsg.Start;}catch (Exception ex){MessageBox.Show(ex.Message);throw;}}

void RecevieMsg{try{//3.1创建 消息缓存区byte arrMsg = new byte[1024 * 1024 * 1];while (isRec){socketMsg.Receive(arrMsg);string strMsg = System.Text.Encoding.UTF8.GetString(arrMsg);ShowMsg("\r\n服务器说:" + strMsg);}}catch (Exception ex){MessageBox.Show(ex.Message);throw;}}

private void btnSend_Click_1(object sender, EventArgs e){string strMsg = this.txtInput.Text.Trim;byte arrMsg = System.Text.Encoding.UTF8.GetBytes(strMsg);socketMsg.Send(arrMsg);this.txtInput.Text = "";}

void ShowMsg(string strmsg){this.txtShow.AppendText(strmsg + "\r\n");}

}

}

最终的效果图如下:

学习Socket编写的聊天室小程序

学习Socket编写的聊天室小程序

4.注意

至少要定义一个要连接的远程主机的IP和端口号。

端口号必须在 1 和 65535之间,最好在1024以后。

要连接的远程主机必须正在监听指定端口,也就是说你无法随意连接远程主机。

如:

IPAddress addr = IPAddress.Parse("127.0.0.1");

IPEndPoint endp = new IPEndPoint(addr, 8989);

服务端先绑定:serverWelcomeSocket.Bind(endp)

客户端再连接:clientSocket.Connect(endp)

一个Socket一次只能连接一台主机。

Socket关闭后无法再次使用。

每个Socket对象只能一台远程主机连接. 如果你想连接到多台远程主机, 你必须创建多个Socket对象

5.扩展

l实现传送文件

如果接收数据是文件还是文字?

设计"协议":

把要传递的字节数组前面都加上一个字节做为标识。0:表示文字 1:表示文件

即:文字: 0+文字(字节数组表示)

文件:1+文件的二进制信息



原网站:http://www.toutiao.com/i6323308820541997569/


推荐阅读
  • 如何在服务器主机上实现文件共享的方法和工具
    本文介绍了在服务器主机上实现文件共享的方法和工具,包括Linux主机和Windows主机的文件传输方式,Web运维和FTP/SFTP客户端运维两种方式,以及使用WinSCP工具将文件上传至Linux云服务器的操作方法。此外,还介绍了在迁移过程中需要安装迁移Agent并输入目的端服务器所在华为云的AK/SK,以及主机迁移服务会收集的源端服务器信息。 ... [详细]
  • Skywalking系列博客1安装单机版 Skywalking的快速安装方法
    本文介绍了如何快速安装单机版的Skywalking,包括下载、环境需求和端口检查等步骤。同时提供了百度盘下载地址和查询端口是否被占用的命令。 ... [详细]
  • 本文介绍了在rhel5.5操作系统下搭建网关+LAMP+postfix+dhcp的步骤和配置方法。通过配置dhcp自动分配ip、实现外网访问公司网站、内网收发邮件、内网上网以及SNAT转换等功能。详细介绍了安装dhcp和配置相关文件的步骤,并提供了相关的命令和配置示例。 ... [详细]
  • Nginx使用(server参数配置)
    本文介绍了Nginx的使用,重点讲解了server参数配置,包括端口号、主机名、根目录等内容。同时,还介绍了Nginx的反向代理功能。 ... [详细]
  • 本文分享了一个关于在C#中使用异步代码的问题,作者在控制台中运行时代码正常工作,但在Windows窗体中却无法正常工作。作者尝试搜索局域网上的主机,但在窗体中计数器没有减少。文章提供了相关的代码和解决思路。 ... [详细]
  • Metasploit攻击渗透实践
    本文介绍了Metasploit攻击渗透实践的内容和要求,包括主动攻击、针对浏览器和客户端的攻击,以及成功应用辅助模块的实践过程。其中涉及使用Hydra在不知道密码的情况下攻击metsploit2靶机获取密码,以及攻击浏览器中的tomcat服务的具体步骤。同时还讲解了爆破密码的方法和设置攻击目标主机的相关参数。 ... [详细]
  • 本文介绍了如何使用iptables添加非对称的NAT规则段,以实现内网穿透和端口转发的功能。通过查阅相关文章,得出了解决方案,即当匹配的端口在映射端口的区间内时,可以成功进行端口转发。详细的操作步骤和命令示例也在文章中给出。 ... [详细]
  • Python瓦片图下载、合并、绘图、标记的代码示例
    本文提供了Python瓦片图下载、合并、绘图、标记的代码示例,包括下载代码、多线程下载、图像处理等功能。通过参考geoserver,使用PIL、cv2、numpy、gdal、osr等库实现了瓦片图的下载、合并、绘图和标记功能。代码示例详细介绍了各个功能的实现方法,供读者参考使用。 ... [详细]
  • 本文讨论了在openwrt-17.01版本中,mt7628设备上初始化启动时eth0的mac地址总是随机生成的问题。每次随机生成的eth0的mac地址都会写到/sys/class/net/eth0/address目录下,而openwrt-17.01原版的SDK会根据随机生成的eth0的mac地址再生成eth0.1、eth0.2等,生成后的mac地址会保存在/etc/config/network下。 ... [详细]
  • 本文详细介绍了cisco路由器IOS损坏时的恢复方法,包括进入ROMMON模式、设置IP地址、子网掩码、默认网关以及使用TFTP服务器传输IOS文件的步骤。 ... [详细]
  • 本文介绍了pack布局管理器在Perl/Tk中的使用方法及注意事项。通过调用pack()方法,可以控制部件在显示窗口中的位置和大小。同时,本文还提到了在使用pack布局管理器时,应注意将部件分组以便在水平和垂直方向上进行堆放。此外,还介绍了使用Frame部件或Toplevel部件来组织部件在窗口内的方法。最后,本文强调了在使用pack布局管理器时,应避免在中间切换到grid布局管理器,以免造成混乱。 ... [详细]
  • Unity3D引擎的体系结构和功能详解
    本文详细介绍了Unity3D引擎的体系结构和功能。Unity3D是一个屡获殊荣的工具,用于创建交互式3D应用程序。它由游戏引擎和编辑器组成,支持C#、Boo和JavaScript脚本编程。该引擎涵盖了声音、图形、物理和网络功能等主题。Unity编辑器具有多语言脚本编辑器和预制装配系统等特点。本文还介绍了Unity的许可证情况。Unity基本功能有限的免费,适用于PC、MAC和Web开发。其他平台或完整的功能集需要购买许可证。 ... [详细]
  • PHP组合工具以及开发所需的工具
    本文介绍了PHP开发中常用的组合工具和开发所需的工具。对于数据分析软件,包括Excel、hihidata、SPSS、SAS、MARLAB、Eview以及各种BI与报表工具等。同时还介绍了PHP开发所需的PHP MySQL Apache集成环境,包括推荐的AppServ等版本。 ... [详细]
  • 概述H.323是由ITU制定的通信控制协议,用于在分组交换网中提供多媒体业务。呼叫控制是其中的重要组成部分,它可用来建立点到点的媒体会话和多点间媒体会议 ... [详细]
  • 1.webkit内核中的一些私有的meta标签,这些meta标签在开发webapp时起到非常重要的作用(1) ... [详细]
author-avatar
mobiledu2502925333
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有