C#Socket多线程编程实例聊天程序文档格式.docx
- 文档编号:22719959
- 上传时间:2023-02-05
- 格式:DOCX
- 页数:13
- 大小:109.20KB
C#Socket多线程编程实例聊天程序文档格式.docx
《C#Socket多线程编程实例聊天程序文档格式.docx》由会员分享,可在线阅读,更多相关《C#Socket多线程编程实例聊天程序文档格式.docx(13页珍藏版)》请在冰豆网上搜索。
所谓连接确认,是指当服务器端套接字监听到或者说接收到客户端套接字的连接请求,它就响应客户端套接字的请求,建立一个新的线程,把服务器端套接字的描述发给客户端,一旦客户端确认了此描述,连接就建立好了。
而服务器端套接字继续处于监听状态,继续接收其他客户端套接字的连接请求。
C#中的套接字编程实例:
通过向大家简单的介绍套接字的基本概念和实现套接字编程的基本原理,我想大家对套接字编程已有了初步的了解。
不过,上面介绍的仅仅是基本概念和原理,要真正运用还是需要一定的工作的。
对基本概念和原理的真正理解的最好方法莫过于自己动手做一个实例,下面我就向大家介绍一个很好的用C#实现套接字编程的实例――聊天室程序。
本程序是基于C/S(服务器/客户端)构架的,程序包含一个服务器端的应用程序和一个客户端的应用程序。
首先,在服务器上运行服务器端的应用程序,该程序一运行就开始服务器监听。
然后,在客户机上就可以打开客户端的应用程序。
程序打开后可以与服务器端应用程序进行连接,即进行客户端请求。
在连接确认后,客户端用户可以和其他的客户端用户进行聊天。
客户端人数没有限制,同时还支持“悄悄话”聊天模式,支持聊天记录。
所以这是一个学习套接字编程的相当不错的例子。
而且,程序中为了处理每个客户端的信息还用到了多线程机制。
在每个客户端与服务器端连接成功后,它们之间就建立一个线程。
这样运用了多线程之后,客户端之间就不会相互影响,即使其中一个出了错误也不会影响到另一个。
下面,我就向大家具体介绍该实例:
服务器端程序:
1.打开VS.net,新建一个C#的模板为“Windows应用程序”的项目,不妨命名为“ChatServer”。
2.布置界面。
只需在界面上添加一个ListBox控件即可,该控件主要用于显示客户端的用户的一些信息的。
图象如下:
3.服务器端程序的代码编写。
对于服务器端,主要的作用是监听客户端的连接请求并确认其请求。
程序一开始便打开一个StartListening()线程。
privatevoidStartListening()
{
listener=newTcpListener(listenport);
listener.Start();
while(true)
try
Sockets=listener.AcceptSocket();
clientsocket=s;
clientservice=newThread(newThreadStart(ServiceClient));
clientservice.Start();
}
catch(Exceptione)
Console.WriteLine(e.ToString());
该线程是一直处于运行状态的。
当服务器端接收到一个来自客户端的连接请求后,它就打开一个ServiceClient()线程来服务客户端。
当一个连接被建立后,每个客户端就被赋予一个属于它自己的套接字。
同时,一个Client类的对象被建立。
该对象包含了客户端的一些相关信息,该信息被保存在一个数组列表中。
Client类如下:
usingSystem;
usingSystem.Threading;
namespaceChatServer
usingSystem.Net.Sockets;
usingSystem.Net;
///
///Client的摘要说明。
publicclassClient
privateThreadclthread;
privateEndPointendpoint;
privatestringname;
privateSocketsock;
publicClient(string_name,EndPoint_endpoint,Thread_thread,Socket_sock)
//TODO:
在此处添加构造函数逻辑
clthread=_thread;
endpoint=_endpoint;
name=_name;
sock=_sock;
publicoverridestringToString()
returnendpoint.ToString()+"
:
"
+name;
publicThreadCLThread
get{returnclthread;
set{clthread=value;
publicEndPointHost
get{returnendpoint;
set{endpoint=value;
publicstringName
get{returnname;
set{name=value;
publicSocketSock
get{returnsock;
set{sock=value;
程序的主体部分应是ServiceClient()函数。
该函数是一个独立的线程,其主要部分是一个while循环。
在循环体内,程序处理各种客户端命令。
服务器端接收来自客户端的以ASCII码给出的字符串,其中包含了一个“|”形式的分隔符。
字符串中“|”以前的部分就是具体的命令,包括CONN、CHAT、PRIV、GONE四种类型。
CONN命令建立一个新的客户端连接,将现有的用户列表发送给新用户并告知其他用户有一个新用户加入。
CHAT命令将新的信息发送给所有用户。
PRIV命令将悄悄话发送给某个用户。
GONE命令从用户列表中除去一个已离开的用户并告知其他的用户某某已经离开了。
同时,GONE命令可以设置布尔型的变量keepalive为false从而结束与客户端连接的线程。
ServiceClient()函数如下:
privatevoidServiceClient()
Socketclient=clientsocket;
boolkeepalive=true;
while(keepalive)
Byte[]buffer=newByte[1024];
client.Receive(buffer);
stringclientcommand=System.Text.Encoding.ASCII.GetString(buffer);
string[]tokens=clientcommand.Split(newChar[]{'
|'
});
Console.WriteLine(clientcommand);
if(tokens[0]=="
CONN"
)
for(intn=0;
n
Clientcl=(Client)clients[n];
SendToClient(cl,"
JOIN|"
+tokens[1]);
EndPointep=client.RemoteEndPoint;
Clientc=newClient(tokens[1],ep,clientservice,client);
clients.Add(c);
stringmessage="
LIST|"
+GetChatterList()+"
\r\n"
;
SendToClient(c,message);
lbClients.Items.Add(c);
CHAT"
SendToClient(cl,clientcommand);
PRIV"
stringdestclient=tokens[3];
if(cl.Name.CompareTo(tokens[3])==0)
if(cl.Name.CompareTo(tokens[1])==0)
GONE"
intremove=0;
boolfound=false;
intc=clients.Count;
remove=n;
found=true;
lbClients.Items.Remove(cl);
if(found)
clients.RemoveAt(remove);
client.Close();
keepalive=false;
}
这样,服务器端程序就基本完成了。
(其他略次要的代码可以参见源代码中的Form1.cs文件)程序运行图示如下:
客户端程序:
1.打开VS.net,新建一个C#的模板为“Windows应用程序”的项目,不妨命名为“ChatClient”。
往界面上添加一个ListBox控件(用于显示用户列表),一个RichTextBox控件(用于显示聊天消息以及系统消息),一个TextBox控件(用于发送消息),一个CheckBox控件(确定是否为悄悄话),一个StatusBar控件以及四个Button控件(分别为“连接”、“断开连接”、“开始记录”、“发送”)。
各个控件的属性设置可以参见源代码中的具体设置,这里从略。
界面设计好后的图象如下:
3.客户端程序的代码编写。
当客户端试图和服务器端进行连接时,一个连接必须建立而且得向服务器端进行注册。
EstablishConnection()函数运用一个TcpClient来和服务器端取得连接,同时创建一个NetworkStream来发送消息。
还有,端口号和服务器端的是保持一致的,均为5555。
EstablishConnection()函数如下:
privatevoidEstablishConnection()
statusBar1.Text="
正在连接到服务器"
clientsocket=newTcpClient(serveraddress,serverport);
ns=clientsocket.GetStream();
sr=newStreamReader(ns);
connected=true;
catch(Exception)
MessageBox.Show("
不能连接到服务器!
"
"
错误"
MessageBoxButtons.OK,MessageBoxIcon.Exclamation);
已断开连接"
在和服务器端连接成功后,程序就用RegisterWithServer()函数向服务器端发送一个CONN命令。
该命令先是发送该用户的名称,然后从服务器端获得其他所有用户的列表,所有用户列表是在ListBox控件中显示的。
该函数如下:
privatevoidRegisterWithServer()
stringcommand="
CONN|"
+ChatOut.Text;
Byte[]outbytes=System.Text.Encoding.ASCII.GetBytes(command.ToCharArray());
ns.Write(outbytes,0,outbytes.Length);
stringserverresponse=sr.ReadLine();
serverresponse.Trim();
string[]tokens=serverresponse.Split(newChar[]{'
if(tokens[0]=="
LIST"
已连接"
btnDisconnect.Enabled=true;
for(intn=1;
lbChatters.Items.Add(tokens[n].Trim(newchar[]{'
\r'
'
\n'
}));
this.Text=clientname+"
:
已连接到服务器"
注册时发生错误!
在此之后,当然就是用户之间的聊天了,由ReceiveChat()函数来完成。
该函数是一个独立的线程,它处理所有用户获得的消息和用户发送的消息。
它主要处理了CHAT、PRIV、JOIN、GONE、QU99v等命令,处理的方法和服务器端的类似。
具体函数实现如下:
privatevoidReceiveChat()
Byte[]buffer=newByte[2048];
ns.Read(buffer,0,buffer.Length);
stringchatter=System.Text.Encoding.ASCII.GetString(buffer);
string[]tokens=chatter.Split(newChar[]{'
rtbChatIn.AppendText(tokens[1]);
if(logging)
logwriter.WriteLine(tokens[1]);
rtbChatIn.AppendText("
Privatefrom"
);
rtbChatIn.AppendText(tokens[1].Trim());
rtbChatIn.AppendText(tokens[2]+"
logwriter.Write("
logwriter.Write(tokens[1].Trim());
logwriter.WriteLine(tokens[2]+"
JOIN"
hasjoinedtheChat\r\n"
logwriter.WriteLine(tokens[1]+"
hasjoinedtheChat"
stringnewguy=tokens[1].Trim(newchar[]{'
lbChatters.Items.Add(newguy);
haslefttheChat\r\n"
haslefttheChat"
lbChatters.Items.Remove(tokens[1].Trim(newchar[]{'
QU99v"
ns.Close();
clientsocket.Close();
服务器端已停止"
connected=false;
btnSend.Enabled=false;
btnDisconnect.Enabled=false;
catch(Exception){}
通过以上的一些函数,客户端程序之间就可以进行自由地聊天了,各个用户之间还可以互相发送悄悄话。
所以程序已经实现了聊天室的基本功能了,不过最后各个用户还要正常地退出,那就要用到QuitChat()函数了。
该函数的具体实现如下:
privatevoidQuitChat()
if(connected)
GONE|"
+clientname;
catch(Exception)
logwriter.Close();
if(receive!
=null&
&
receive.IsAlive)
receive.Abort();
this.Text="
客户端"
到此为止,客户端程序的主要部分都已经介绍完毕。
还有一些按钮控件的消息处理函数可以参见源代码。
同时,程序中还有一个聊天记录功能,该功能和现在流行的聊天软件的记录功能类似。
不过限于篇幅,在这里就不一一介绍了,有兴趣的读者可以研究一下本文后面的源代码。
这样,客户端程序就完成了。
程序运行图示如下:
总结:
本文向大家初步介绍了套接字的基本概念和实现套接字编程的基本原理,还通过一个很好的实例向大家展示了在C#下进行套接字编程的实现方法和一些编程技巧。
从中,我们不难发现运用C#进行套接字编程乃至网络编程有许多优越之处。
实例程序实现的思路清晰明了而且通俗易懂,是一个相当不错的例子,希望各位能好好研读。
同时还希望大家能进一步完善该程序,使之功能更强大、界面更友好。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Socket 多线程 编程 实例 聊天 程序