C# Socket多线程编程实例.docx

上传人:牧羊曲112 文档编号:4883236 上传时间:2023-05-21 格式:DOCX 页数:12 大小:119.97KB
返回 下载 相关 举报
C# Socket多线程编程实例.docx_第1页
第1页 / 共12页
C# Socket多线程编程实例.docx_第2页
第2页 / 共12页
C# Socket多线程编程实例.docx_第3页
第3页 / 共12页
C# Socket多线程编程实例.docx_第4页
第4页 / 共12页
C# Socket多线程编程实例.docx_第5页
第5页 / 共12页
亲,该文档总共12页,到这儿已超出免费预览范围,如果喜欢就下载吧!
资源描述

《C# Socket多线程编程实例.docx》由会员分享,可在线阅读,更多相关《C# Socket多线程编程实例.docx(12页珍藏版)》请在三一办公上搜索。

1、C# Socket多线程编程实例C#是微软随着VS.net新推出的一门语言。它作为一门新兴的语言,有着C+的强健,又有 着VB等的RAD特性。而且,微软推出C#主要的目的是为了对抗Sun公司的Java。大家都 知道Java语言的强大功能,尤其在网络编程方面。于是,C#在网络编程方面也自然不甘落 后于人。本文就向大家介绍一下C#下实现套接字(Sockets)编程的一些基本知识,以期能 使大家对此有个大致了解。首先,我向大家介绍一下套接字的概念。套接字基本概念:套接字是通信的基石,是支持TCP/IP协议的网络通信的基本操作单元。可以将套接字 看作不同主机间的进程进行双向通信的端点,它构成了单个主机

2、内及整个网络间的编程界 面。套接字存在于通信域中,通信域是为了处理一般的线程通过套接字通信而引进的一种抽 象概念。套接字通常和同一个域中的套接字交换数据(数据交换也可能穿越域的界限,但这 时一定要执行某种解释程序)。各种进程使用这个相同的域互相之间用Internet协议簇来进 行通信。套接字可以根据通信性质分类,这种性质对于用户是可见的。应用程序一般仅在同一 类的套接字间进行通信。不过只要底层的通信协议允许,不同类型的套接字间也照样可以通 信。套接字有两种不同的类型:流套接字和数据报套接字。套接字工作原理:要通过互联网进行通信,你至少需要一对套接字,其中一个运行于客户机端,我们称 之为Clie

3、ntSocket,另一个运行于服务器端,我们称之为ServerSocket。根据连接启动的方式以及本地套接字要连接的目标,套接字之间的连接过程可以分为 三个步骤:服务器监听,客户端请求,连接确认。所谓服务器监听,是服务器端套接字并不定位具体的客户端套接字,而是处于等待连 接的状态,实时监控网络状态。所谓客户端请求,是指由客户端的套接字提出连接请求,要连接的目标是服务器端的 套接字。为此,客户端的套接字必须首先描述它要连接的服务器的套接字,指出服务器端套 接字的地址和端口号,然后就向服务器端套接字提出连接请求。所谓连接确认,是指当服务器端套接字监听到或者说接收到客户端套接字的连接请求, 它就响应

4、客户端套接字的请求,建立一个新的线程,把服务器端套接字的描述发给客户端, 一旦客户端确认了此描述,连接就建立好了。而服务器端套接字继续处于监听状态,继续接 收其他客户端套接字的连接请求。C#中的套接字编程实例:通过向大家简单的介绍套接字的基本概念和实现套接字编程的基本原理,我想大家对 套接字编程已有了初步的了解。不过,上面介绍的仅仅是基本概念和原理,要真正运用还是 需要一定的工作的。对基本概念和原理的真正理解的最好方法莫过于自己动手做一个实例,下面我就向大家介绍一个很好的用C#实现套接字编程的实例一一聊天室程序。本程序是基于C/S (服务器/客户端)构架的,程序包含一个服务器端的应用程序和一

5、个客户端的应用程序。首先,在服务器上运行服务器端的应用程序,该程序一运行就开始服 务器监听。然后,在客户机上就可以打开客户端的应用程序。程序打开后可以与服务器端应 用程序进行连接,即进行客户端请求。在连接确认后,客户端用户可以和其他的客户端用户 进行聊天。客户端人数没有限制,同时还支持,肖悄话”聊天模式,支持聊天记录。所以这是 一个学习套接字编程的相当不错的例子。而且,程序中为了处理每个客户端的信息还用到了 多线程机制。在每个客户端与服务器端连接成功后,它们之间就建立一个线程。这样运用了 多线程之后,客户端之间就不会相互影响,即使其中一个出了错误也不会影响到另一个。下面,我就向大家具体介绍该实

6、例:服务器端程序:1. 打开VS.net,新建一个C#的模板为“Windows应用程序”的项目,不妨命名为 “ChatServer”。2. 布置界面。只需在界面上添加一个ListBox控件即可,该控件主要用于显示客户 端的用户的一些信息的。图象如下:3. 服务器端程序的代码编写。对于服务器端,主要的作用是监听客户端的连接请求并确认其请求。程序一开始便打开一个StartListening ()线程。private void StartListening()listener = new TcpListener(listenport);listener.Start();while (true)try

7、Socket s = listener.AcceptSocket();clientsocket = s;clientservice = new Thread(new ThreadStart(ServiceClient);clientservice.Start();catch(Exception e)Console.WriteLine(e.ToString();该线程是一直处于运行状态的。当服务器端接收到一个来自客户端的连接请求后,它 就打开一个ServiceClient()线程来服务客户端。当一个连接被建立后,每个客户端就被赋 予一个属于它自己的套接字。同时,一个Client类的对象被建立。该

8、对象包含了客户端的一 些相关信息,该信息被保存在一个数组列表中。Client类如下:using System;using System.Threading;namespace ChatServer using System.Net.Sockets;using System.Net;/ Client的摘要说明。/public class Clientprivate Thread clthread;private EndPoint endpoint;private string name;private Socket sock;public Client(string _name, EndPoin

9、t _endpoint, Thread _thread, Socket _sock) / TODO:在此处添加构造函数逻辑clthread = _thread;endpoint = _endpoint;name = _name;sock = _sock;public override string ToString()return endpoint.ToString()+ : + name;public Thread CLThreadgetreturn clthread;setclthread = value;public EndPoint Hostgetreturn endpoint;set

10、endpoint = value;public string Namegetreturn name;setname = value;public Socket Sockgetreturn sock;setsock = value;程序的主体部分应是ServiceClient ()函数。该函数是一个独立的线程,其主要部分 是一个while循环。在循环体内,程序处理各种客户端命令。服务器端接收来自客户端的以 ASCII码给出的字符串,其中包含了一个“|”形式的分隔符。字符串中T以前的部分就是具体 的命令,包括CONN、CHAT、PRIV、GONE四种类型。CONN命令建立一个新的客户端 连接,将现

11、有的用户列表发送给新用户并告知其他用户有一个新用户加入。CHAT命令将新 的信息发送给所有用户。PRIV命令将悄悄话发送给某个用户。GONE命令从用户列表中除 去一个已离开的用户并告知其他的用户某某已经离开了。同时,GONE命令可以设置布尔型 的变量keepalive为false从而结束与客户端连接的线程。ServiceClient()函数如下:private void ServiceClient()Socket client = clientsocket;bool keepalive = true;while (keepalive)Byte buffer = new Byte1024;cli

12、ent.Receive(buffer);string clientcommand = System.Text.Encoding.ASCII.GetString(buffer);string tokens = clientcommand.Split(new Char|);Console.WriteLine(clientcommand);if (tokens0 = CONN)for(int n=0; nClient cl = (Client)clientsn;SendToClient(cl, JOIN| + tokens1);EndPoint ep = client.RemoteEndPoint;

13、Client c = new Client(tokens1, ep, clientservice, client);clients.Add(c);string message = LIST| + GetChatterList() +rn;SendToClient(c, message);lbClients.Items.Add(c);if (tokens0 = CHAT)for(int n=0; nClient cl = (Client)clientsn;SendToClient(cl, clientcommand);if (tokens0 = PRIV)string destclient =

14、tokens3;for(int n=0; nClient cl = (Client)clientsn;if(cl.Name.CompareTo(tokens3) = 0)SendToClient(cl, clientcommand);if(cl.Name.CompareTo(tokens1) = 0)SendToClient(cl, clientcommand);if (tokens0 = GONE)int remove = 0;bool found = false;int c = clients.Count;for(int n=0; nClient cl = (Client)clientsn

15、;SendToClient(cl, clientcommand);if(cl.Name.CompareTo(tokens1) = 0) remove = n;found = true;lbClients.Items.Remove(cl);if(found)clients.RemoveAt(remove);client.Close();keepalive = false;这样,服务器端程序就基本完成了。(其他略次要的代码可以参见源代码中的Form1.cs文件) 程序运行图示如下:客户端程序:1. 打开VS.net,新建一个C#的模板为“Windows应用程序”的项目,不妨命名为 “ChatCli

16、ent”。2. 布置界面。往界面上添加一个ListBox控件(用于显示用户列表),一个RichTextBox 控件(用于显示聊天消息以及系统消息),一个TextBox控件(用于发送消息),一个CheckBox 控件(确定是否为悄悄话),一个StatusBar控件以及四个Button控件(分别为“连接”、“断 开连接”、“开始记录”、“发送”)。各个控件的属性设置可以参见源代码中的具体设置,这里 从略。界面设计好后的图象如下:Jnld_:|:|9 O 5 5 6 o o OPitt D o o s e Fr:=Lrik= 127.0.0. 1:1061Err.il:上传于【新客网 W. XKEE

17、.COM3.客户端程序的代码编写。当客户端试图和服务器端进行连接时,一个连接必须建立而且得向服务器端进行注册。EstablishConnection ()函数运用一个 TcpClient来和服务器端取得连接,同时创建一个 NetworkStream来发送消息。还有,端口号和服务器端的是保持一致的,均为5555。EstablishConnection ()函数如下:private void EstablishConnection()statusBar1.Text =正在连接到服务器”;tryclientsocket = new TcpClient(serveraddress,serverport

18、);ns = clientsocket.GetStream();sr = new StreamReader(ns);connected = true;catch (Exception)MessageBox.Show(不能连接到服务器!”,”错误”,MessageBoxButtons.OK, MessageBoxIcon.Exclamation);statusBar1.Text = ”已断开连接”;在和服务器端连接成功后,程序就用RegisterWithServer ()函数向服务器端发送一个 CONN命令。该命令先是发送该用户的名称,然后从服务器端获得其他所有用户的列表, 所有用户列表是在Li

19、stBox控件中显示的。该函数如下:private void RegisterWithServer()trystring command = CONNI + ChatOut.Text;Byte outbytes = System.Text.Encoding.ASCII.GetBytes(command.ToCharArray();ns.Write(outbytes,0,outbytes.Length);string serverresponse = sr.ReadLine();serverresponse.Trim();string tokens = serverresponse.Split(

20、new Char|);if(tokens0 = LIST)statusBar1.Text =已连接;btnDisconnect.Enabled = true;for(int n=1; nlbChatters.Items.Add(tokensn.Trim(new charr,n);this.Text = clientname + :已连接到服务器;catch (Exception)MessageBox.ShowC注册时发生错误!”,”错误”,MessageBoxButtons.OK, MessageBoxIcon.Exclamation);在此之后,当然就是用户之间的聊天了,由ReceiveCh

21、at ()函数来完成。该函数是一个独 立的线程,它处理所有用户获得的消息和用户发送的消息。它主要处理了 CHAT、PRIV、 JOIN、GONE、QU99v等命令,处理的方法和服务器端的类似。具体函数实现如下:private void ReceiveChat()bool keepalive = true;while (keepalive)tryByte buffer = new Byte2048;ns.Read(buffer,0,buffer.Length);string chatter = System.Text.Encoding.ASCII.GetString(buffer);string

22、 tokens = chatter.Split(new Char|);if (tokens0 = CHAT)rtbChatIn.AppendText(tokens1);if(logging)logwriter.WriteLine(tokens1);if (tokens0 = PRIV)rtbChatIn.AppendText(Private from );rtbChatIn.AppendText(tokens1.Trim();rtbChatIn.AppendText(tokens + rn);if(logging)logwriter.Write(Private from );logwriter

23、.Write(tokens1.Trim();logwriter.WriteLine(tokens2 + rn);if (tokens0 = JOIN)rtbChatIn.AppendText(tokens1.Trim();rtbChatIn.AppendText( has joined the Chatrn);if(logging)logwriter.WriteLine(tokens1+ has joined the Chat);string newguy = tokens1.Trim(new charr,n);lbChatters.Items.Add(newguy);if (tokens0

24、= GONE)rtbChatIn.AppendText(tokens1.Trim();rtbChatIn.AppendText( has left the Chatrn);if(logging)logwriter.WriteLine(tokens1+ has left the Chat);lbChatters.Items.Remove(tokens1.Trim(new charr,n);if (tokens0 = QU99v)ns.Close();clientsocket.Close();keepalive = false;statusBarl.Text =服务器端已停止”;connected

25、 false;btnSend.Enabled = false;btnDisconnect.Enabled = false;catch(Exception)(通过以上的一些函数,客户端程序之间就可以进行自由地聊天了,各个用户之间还可 以互相发送悄悄话。所以程序已经实现了聊天室的基本功能了,不过最后各个用户还要正常 地退出,那就要用到QuitChat()函数了。该函数的具体实现如下:private void QuitChat()if(connected)trystring command = GONE! + clientname;Byte outbytes = System.Text.Encodi

26、ng.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 =客户端”;到此为止,客户端程序的主要部分都已经介绍完毕。还有一些按钮控件的消息处理函 数可以参见源代码。同时,程序中还有一个聊天记录功能,该功能和现在流行的聊天软件的 记录功能类似。不过

27、限于篇幅,在这里就不一一介绍了,有兴趣的读者可以研究一下本文后 面的源代码。这样,客户端程序就完成了。程序运行图示如下:-,1n| xj虔Frank :已连接到服藩器PittD o o e eFr :=LTikEmiLEmily has j o i ne d the ChatEmily: Hello everyb u dy! !Pitt: rm Pitt! ! !Dooee: Duoee is here!Private rom Frank: Emily; I love you so deeply!Private rom Emily: Oh, Frik, me too. me too! ! !连接断开连接开始记录回悄悄话上准亍t新客网 W. XKER. COM总结:本文向大家初步介绍了套接字的基本概念和实现套接字编程的基本原理,还通过一个 很好的实例向大家展示了在。#下进行套接字编程的实现方法和一些编程技巧。从中,我们 不难发现运用C#进行套接字编程乃至网络编程有许多优越之处。实例程序实现的思路清晰 明了而且通俗易懂,是一个相当不错的例子,希望各位能好好研读。同时还希望大家能进一 步完善该程序,使之功能更强大、界面更友好。

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 生活休闲 > 在线阅读


备案号:宁ICP备20000045号-2

经营许可证:宁B2-20210002

宁公网安备 64010402000987号