浅析C#中的套接字编程
套接字是通信的基石,是支持TCP/IP协议的网络通信的基本操作单元。可以将套接字看作不同主机间的进程进行双向通信的端点,它构成了单个主机内及整个网络间的编程界面。套接字存在于通信域中,通信域是为了处理一般的线程通过套接字通信而引进的一种抽象概念。套接字通常和同一个域中的套接字交换数据(数据交换也可能穿越域的界限,但这时一定要执行某种解释程序)。各种进程使用这个相同的域互相之间用Internet协议簇来进行通信。
套接字可以根据通信性质分类,这种性质对于用户是可见的。应用程序一般仅在同一类的套接字间进行通信。不过只要底层的通信协议允许,不同类型的套接字间也照样可以通信。套接字有两种不同的类型:流套接字和数据报套接字。
套接字工作原理:
要通过互联网进行通信,你至少需要一对套接字,其中一个运行于客户机端,我们称之为ClientSocket,另一个运行于服务器端,我们称之为ServerSocket。
根据连接启动的方式以及本地套接字要连接的目标,套接字之间的连接过程可以分为三个步骤:服务器监听,客户端请求,连接确认。
所谓服务器监听,是服务器端套接字并不定位具体的客户端套接字,而是处于等待连接的状态,实时监控网络状态。
所谓客户端请求,是指由客户端的套接字提出连接请求,要连接的目标是服务器端的套接字。为此,客户端的套接字必须首先描述它要连接的服务器的套接字,指出服务器端套接字的地址和端口号,然后就向服务器端套接字提出连接请求。
所谓连接确认,是指当服务器端套接字监听到或者说接收到客户端套接字的连接请求,它就响应客户端套接字的请求,建立一个新的线程,把服务器端套接字的描述发给客户端,一旦客户端确认了此描述,连接就建立好了。而服务器端套接字继续处于监听状态,继续接收其他客户端套接字的连接请求。
C#中的套接字编程实例:
通过向大家简单的介绍套接字的基本概念和实现套接字编程的基本原理,我想大家对套接字编程已有了初步的了解。不过,上面介绍的仅仅是基本概念和原理,要真正运用还是需要一定的工作的。
对基本概念和原理的真正理解的最好方法莫过于自己动手做一个实例,下面我就向大家介绍一个很好的用C#实现套接字编程的实例――聊天室程序。
本程序是基于C/S(服务器/客户端)构架的,程序包含一个服务器端的应用程序和一个客户端的应用程序。首先,在服务器上运行服务器端的应用程序,该程序一运行就开始服务器监听。然后,在客户机上就可以打开客户端的应用程序。程序打开后可以与服务器端应用程序进行连接,即进行客户端请求。在连接确认后,客户端用户可以和其他的客户端用户进行聊天。客户端人数没有限制,同时还支持“悄悄话”聊天模式,支持聊天记录。所以这是一个学习套接字编程的相当不错的例子。而且,程序中为了处理每个客户端的信息还用到了多线程机制。在每个客户端与服务器端连接成功后,它们之间就建立一个线程。这样运用了多线程之后,客户端之间就不会相互影响,即使其中一个出了错误也不会影响到另一个。
下面,我就向大家具体介绍该实例:
服务器端程序:
1. 打开VS.net,新建一个C#的模板为“Windows 应用程序”的项目,不妨命名为“ChatServer”。
2. 布置界面。只需在界面上添加一个ListBox控件即可,该控件主要用于显示客户端的用户的一些信息的。图象如下:
3. 服务器端程序的代码编写。
对于服务器端,主要的作用是监听客户端的连接请求并确认其请求。程序一开始便打开一个StartListening()线程。
private void StartListening() { listener = new TcpListener(listenport); listener.Start(); while (true) { try { Socket s = listener.AcceptSocket(); clientsocket = s; clientservice = new Thread(new ThreadStart(ServiceClient)); clientservice.Start(); } catch(Exception e) { Console.WriteLine(e.ToString() ); } } } |
该线程是一直处于运行状态的。当服务器端接收到一个来自客户端的连接请求后,它就打开一个ServiceClient()线程来服务客户端。当一个连接被建立后,每个客户端就被赋予一个属于它自己的套接字。同时,一个Client类的对象被建立。该对象包含了客户端的一些相关信息,该信息被保存在一个数组列表中。
Client类如下:
using System; using System.Threading; namespace ChatServer /// public Client(string _name, EndPoint _endpoint, Thread _thread, Socket _sock) public override string ToString() public Thread CLThread public EndPoint Host public string Name public Socket Sock |
程序的主体部分应是ServiceClient()函数。该函数是一个独立的线程,其主要部分是一个while循环。在循环体内,程序处理各种客户端命令。服务器端接收来自客户端的以ASCII码给出的字符串,其中包含了一个“|”形式的分隔符。字符串中“|”以前的部分就是具体的命令,包括CONN、CHAT、PRIV、GONE四种类型。CONN命令建立一个新的客户端连接,将现有的用户列表发送给新用户并告知其他用户有一个新用户加入。CHAT命令将新的信息发送给所有用户。PRIV命令将悄悄话发送给某个用户。GONE命令从用户列表中除去一个已离开的用户并告知其他的用户某某已经离开了。同时,GONE命令可以设置布尔型的变量keepalive为false从而结束与客户端连接的线程。ServiceClient()函数如下:
private void ServiceClient() { Socket client = clientsocket; bool keepalive = true; while (keepalive) string[] tokens = clientcommand.Split(new Char[]{'|'}); if (tokens[0] == "CONN") lbClients.Items.Add(c); } |
这样,服务器端程序就基本完成了。(其他略次要的代码可以参见源代码中的Form1.cs文件)程序运行图示如下:
客户端程序:
1. 打开VS.net,新建一个C#的模板为“Windows 应用程序”的项目,不妨命名为“ChatClient”。
2. 布置界面。往界面上添加一个ListBox控件(用于显示用户列表),一个RichTextBox控件(用于显示聊天消息以及系统消息),一个TextBox控件(用于发送消息),一个CheckBox控件(确定是否为悄悄话),一个StatusBar控件以及四个Button控件(分别为“连接”、“断开连接”、“开始记录”、“发送”)。各个控件的属性设置可以参见源代码中的具体设置,这里从略。界面设计好后的图象如下:
当客户端试图和服务器端进行连接时,一个连接必须建立而且得向服务器端进行注册。 EstablishConnection()函数运用一个TcpClient来和服务器端取得连接,同时创建一个NetworkStream来发送消息。还有,端口号和服务器端的是保持一致的,均为5555。EstablishConnection()函数如下:
private void EstablishConnection() { statusBar1.Text = "正在连接到服务器"; try { clientsocket = new TcpClient(serveraddress,serverport); ns = clientsocket.GetStream(); sr = new StreamReader(ns); connected = true; } catch (Exception) { MessageBox.Show("不能连接到服务器!","错误", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); statusBar1.Text = "已断开连接"; } } |
在和服务器端连接成功后,程序就用RegisterWithServer()函数向服务器端发送一个CONN命令。该命令先是发送该用户的名称,然后从服务器端获得其他所有用户的列表,所有用户列表是在ListBox控件中显示的。该函数如下:
private void RegisterWithServer() { try { string command = "CONN|" + ChatOut.Text; Byte[] outbytes = System.Text.Encoding.ASCII.GetBytes(command.ToCharArray()); ns.Write(outbytes,0,outbytes.Length); string serverresponse = sr.ReadLine(); } |
在此之后,当然就是用户之间的聊天了,由ReceiveChat()函数来完成。该函数是一个独立的线程,它处理所有用户获得的消息和用户发送的消息。它主要处理了CHAT、PRIV、JOIN、GONE、QUIT等命令,处理的方法和服务器端的类似。具体函数实现如下:
private void ReceiveChat() { bool keepalive = true; while (keepalive) { try { Byte[] buffer = new Byte[2048]; ns.Read(buffer,0,buffer.Length); string chatter = System.Text.Encoding.ASCII.GetString(buffer); string[] tokens = chatter.Split(new Char[]{'|'}); if (tokens[0] == "CHAT") |
通过以上的一些函数,客户端程序之间就可以进行自由地聊天了,各个用户之间还可以互相发送悄悄话。所以程序已经实现了聊天室的基本功能了,不过最后各个用户还要正常地退出,那就要用到QuitChat()函数了。该函数的具体实现如下:
private void QuitChat() { if(connected) { try { string command = "GONE|" + clientname; Byte[] outbytes = System.Text.Encoding.ASCII.GetBytes(command.ToCharArray()); ns.Write(outbytes,0,outbytes.Length); clientsocket.Close(); } catch(Exception) { } } if(logging) logwriter.Close(); if(receive != null && receive.IsAlive) receive.Abort(); this.Text = "客户端"; } |
到此为止,客户端程序的主要部分都已经介绍完毕。还有一些按钮控件的消息处理函数可以参见源代码。同时,程序中还有一个聊天记录功能,该功能和现在流行的聊天软件的记录功能类似。不过限于篇幅,在这里就不一一介绍了,有兴趣的读者可以研究一下本文后面的源代码。
这样,客户端程序就完成了。程序运行图示如下:
转载于:https://www.cnblogs.com/Aioria0622/archive/2007/12/03/980880.html
浅析C#中的套接字编程相关推荐
- 什么是Python中的套接字编程?
摘要:本文涵盖了有关使用Python进行套接字编程的所有领域.套接字可以帮助您建立这些连接,而Python无疑可以简化连接. 本文分享自华为云社区<从零开始学python | 什么是Python ...
- C#中的套接字编程(一) --转
TCP/IP 体系结构与特点 TCP/IP协议实际上就是在物理网上的一组完整的网络协议.其中TCP是提供传输层服务,而IP则是提供网络层服务.TCP/IP包括以下协议: IP:网间协议 ...
- Python中的套接字编程
文章目录 **连接到服务器:** **一个简单的服务器客户端程序:** **服务器** **客户端** 套接字编程是一种连接网络上的两个节点以相互通信的方法.一个套接字(节点)侦听 IP 处的特定端口 ...
- C#中的套接字编程(二) --转
客户端程序的代码编写: 布置界面.往界面上添加一个ListBox控件(用于显示用户列表),一个RichTextBox控件(用于显示聊天消息以及系统消息),一个 TextBox控件(用于发送消息 ...
- java套接字编程_Java套接字编程:教程
java套接字编程 本教程是Java套接字编程的简介,从一个简单的客户机-服务器示例开始,该示例演示了Java I / O的基本功能. 将向您介绍原始的java.io软件包和NIO,即Java 1.4 ...
- python中typeerror怎么解决_Python 3中套接字编程中遇到TypeError: 'str' does not support the buffer interface的解决办法...
目前正在学习python,使用的工具为python3.2.3.发现3x版本和2x版本有些差异,在套接字编程时,困扰了我很久,先将python核心编程书中的例子 代码如下: 服务器端: #Echo se ...
- 套接字编程---2(TCP套接字编程的流程,TCP套接字编程中的接口函数,TCP套接字的实现,TCP套接字出现的问题,TCP套接字多进程版本,TCP套接字多线程版本)
TCP模型创建流程图 TCP套接字编程中的接口 socket 函数 #include <sys/types.h> /* See NOTES */ #include <sys/sock ...
- Linux 套接字编程中的 5 个隐患
Linux 套接字编程中的 5 个隐患 (2011-05-03 17:50) 分类: Socket编程 在 4.2 BSD UNIX® 操作系统中首次引入,Sockets API 现在是任何操作系统的 ...
- 原始套接字编程”中的Teardrop代码编程
原始套接字编程"中的Teardrop代码编程 (1)实验代码: #include <stdio.h> #include <stdlib.h> #include < ...
最新文章
- 34.在排序数组中查找元素的起始和末尾位置
- 混合云关键技术能力和发展趋势
- 【记录】ASP.NET IIS ISAPI_Rewrite
- 大脑体操:三桶分水问题
- Win7-VirsualBox下学习Ubuntu--初识ubuntu
- 万字综述,GNN在NLP中的应用,建议收藏慢慢看
- WCF框架基础(一)
- linux每个phy一个接口,mdio
- 基于Java、MySQL的毕业设计,房屋租赁系统
- MediaSession框架全解析
- Datagrid Bind DropDownlist.....
- tensorflow如何使用tensorboard将图片文件events.out.tfevents.1618410161.DESKTOP-CLCBFNS展示出来
- 隐藏的BUG探讨——从“Y2K”问题到“2038”年问题
- 数据库拆分的理解和案例(详细版)
- 【安全牛学习笔记】反射型XSS***漏洞的原理及解决办法
- STM32+OpenMV+AS608实现人脸识别
- hust_os_shell算命大师
- 转:一个硕士应届生的面试总结.(很精彩,特别是具体的各公司面试信息)
- 一分钟定制CocosCreator加载页面
- 电子计算机绘制地图的引进,简述Adobe Illustrator地图编制的方法
热门文章
- 老域名优化出新招,三点技巧来相助
- 营销网站SEO优化:前方优化难点出没!
- 女生学计算机教学,女生学计算机专业好吗 计算机辅助数学教学之我见
- 服务器如何开启远程控制,远程控制命令设置方法介绍
- python索引右往左_[Python笔记]序列(一)索引、分片
- 趣谈网络协议笔记-二(第十九讲)
- 左转待转区----当同向直行信号灯绿灯亮时,左转弯的车辆进入左转待转区等候放行信号(即使此时左转弯灯是红色的) 注意:当直行红灯时候禁止进入...
- python nltk 入门demo
- Angular-cli生成组件修改css成less或sass
- Eclipse使用新手教程