根据Socket的聊天室C版Word文档下载推荐.docx

上传人:b****6 文档编号:8350732 上传时间:2023-05-11 格式:DOCX 页数:32 大小:280.69KB
下载 相关 举报
根据Socket的聊天室C版Word文档下载推荐.docx_第1页
第1页 / 共32页
根据Socket的聊天室C版Word文档下载推荐.docx_第2页
第2页 / 共32页
根据Socket的聊天室C版Word文档下载推荐.docx_第3页
第3页 / 共32页
根据Socket的聊天室C版Word文档下载推荐.docx_第4页
第4页 / 共32页
根据Socket的聊天室C版Word文档下载推荐.docx_第5页
第5页 / 共32页
根据Socket的聊天室C版Word文档下载推荐.docx_第6页
第6页 / 共32页
根据Socket的聊天室C版Word文档下载推荐.docx_第7页
第7页 / 共32页
根据Socket的聊天室C版Word文档下载推荐.docx_第8页
第8页 / 共32页
根据Socket的聊天室C版Word文档下载推荐.docx_第9页
第9页 / 共32页
根据Socket的聊天室C版Word文档下载推荐.docx_第10页
第10页 / 共32页
根据Socket的聊天室C版Word文档下载推荐.docx_第11页
第11页 / 共32页
根据Socket的聊天室C版Word文档下载推荐.docx_第12页
第12页 / 共32页
根据Socket的聊天室C版Word文档下载推荐.docx_第13页
第13页 / 共32页
根据Socket的聊天室C版Word文档下载推荐.docx_第14页
第14页 / 共32页
根据Socket的聊天室C版Word文档下载推荐.docx_第15页
第15页 / 共32页
根据Socket的聊天室C版Word文档下载推荐.docx_第16页
第16页 / 共32页
根据Socket的聊天室C版Word文档下载推荐.docx_第17页
第17页 / 共32页
根据Socket的聊天室C版Word文档下载推荐.docx_第18页
第18页 / 共32页
根据Socket的聊天室C版Word文档下载推荐.docx_第19页
第19页 / 共32页
根据Socket的聊天室C版Word文档下载推荐.docx_第20页
第20页 / 共32页
亲,该文档总共32页,到这儿已超出免费预览范围,如果喜欢就下载吧!
下载资源
资源描述

根据Socket的聊天室C版Word文档下载推荐.docx

《根据Socket的聊天室C版Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《根据Socket的聊天室C版Word文档下载推荐.docx(32页珍藏版)》请在冰点文库上搜索。

根据Socket的聊天室C版Word文档下载推荐.docx

连接聊天室服务器

JOIN:

加入聊天(通知其他用户本人已经加入聊天室服务器)

LIST:

列出所有的用户(向客户端发送全部的登录用户名字)

CHAT:

发送聊天信息(公开的聊天信息)

PRIV:

进行私聊(三个参数:

私聊信息用户;

接收私聊信息用户;

发送信息)

EXIT:

客户端向服务器发送离开请求;

QUIT:

退出聊天,服务器向客户端发送退出命令(执行QUIT命令聊天状态变为CLOSED)

四、系统实现

服务器协议解析:

当有客户端连接聊天室服务器后,服务器立刻为这个客户建立一个数据接收的线程(多用户程序必备)。

在接收线程中,如果收到聊天命令,就对其进行解析处理,服务器可以处理五种命令:

CONN\LIST\CHAT\PRIV\EXIT。

服务器接收到CONN命令,就向其他用户发送JOIN命令告诉有用户加入,然后把当前的全部用户信息返回给刚刚加入的用户,以便在界面上显示用户列表。

当接收到EXIT命令后,就清除当前用户的信息,然后向其他用户发送QUIT命令,告诉其他用户退出了,这些用户的客户端把离开的用户从用户列表中删除。

聊天室客户端的协议解析:

当客户端连接到服务器后,服务器立刻建立一个数据接收的独立线程。

在接收线程中,如果收到了聊天命令,就对其进行解析处理。

聊天室客户端一共处理的命令有五种:

OK\ERR\LIST\JOIN\QUIT命令。

五、程序设计(代码)

服务器端设计:

引入网络操作命名空间System.Net、System.Net.Sockets;

线程处理命名空间System.Threading

第一步:

界面设计及类与相关成员的定义

对界面进行设计(简单)

对内部函数进行设计(要编写一个独立的类即Client类,封装了客户端的信息与连接,每一个客户进入聊天室,就创建一个Client对象,用于保存该用户的信息并接收用户数据和发送信息到客户端)

几个重要的类:

TcpListener类(服务器套接字创建)、Socket类

internalstaticHashtableclients=newHashtable();

//clients数组保存当前在线用户的client对象

privateTcpListenerlistener;

//该服务器默认的监听端口号

staticintMAX_NUM=100;

//服务器可以支持的客户端的最大连接数

internalstaticboolSocketServiceFlag=false;

//开始服务的标志

//获得本地局域网或者拨号动态分配的IP地址,在启动服务器时会用到IP地址

privatestringgetIPAddress()

{

//获得本机局域网IP地址

IPAddress[]Addresslist=Dns.GetHostEntry(Dns.GetHostName()).AddressList;

if(Addresslist.Length<

1)

return"

"

;

}

returnAddresslist[0].ToString();

//获得动态的IP地址

privatestaticstringgetDynamicIPAddress()

IPAddress[]Addresslist=Dns.GetHostEntry(Dns.GetHostName()).AddressList;

if(Addresslist.Length<

2)

returnAddresslist[1].ToString();

//服务器监听的端口号通过getValidPort()函数获得

privateintgetValidPort(stringport)

intlport;

//测试端口号是否有效

try

//是否为空

if(port=="

thrownewArgumentException("

端口号为空,不能启动服务器"

);

lport=System.Convert.ToInt32(port);

catch(Exceptione)

Console.WriteLine("

无效的端口号:

+e.ToString());

this.rtbSocketMsg.AppendText("

+e.ToString()+"

\n"

return-1;

returnlport;

privatevoidbtnSocketStart_Click(objectsender,EventArgse)

intport=getValidPort(tbSocketPort.Text);

if(port<

0)

return;

stringip=this.getIPAddress();

IPAddressipAdd=IPAddress.Parse(ip);

listener=newTcpListener(ipAdd,port);

//创建服务器套接字

listener.Start();

//开始监听服务器端口

Socket服务器已经启动,正在监听"

+ip+"

端口号:

+this.tbSocketPort.Text+"

//启动一个新的线程,执行方法this.StartSocketListen,

//以便在一个独立的进程中执行确认与客户端Socket连接的操作

Form1.SocketServiceFlag=true;

Threadthread=newThread(newThreadStart(this.StartSocketListen));

thread.Start();

this.btnSocketStart.Enabled=false;

this.btnSocketStop.Enabled=true;

catch(Exceptionex)

this.rtbSocketMsg.AppendText(ex.Message.ToString()+"

//在新的线程中的操作,它主要用于当接收到一个客户端请求时,确认与客户端的链接

//并且立刻启动一个新的线程来处理和该客户端的信息交互

privatevoidStartSocketListen()

while(Form1.SocketServiceFlag)

//当接收到一个客户端请求时,确认与客户端的链接

if(listener.Pending())//确认是否有挂起的连接请求

Socketsocket=listener.AcceptSocket();

//接收挂起的连接请求

if(clients.Count>

=MAX_NUM)

已经达到了最大连接数:

+MAX_NUM+"

拒绝新的链接\n"

socket.Close();

else

//启动一个新的线程

//执行方法this.ServiceClient,处理用户相应的请求

ChatSever.Client.Clientclient=newChatSever.Client.Client(this,socket);

ThreadclientService=newThread(newThreadStart(client.ServiceClient));

clientService.Start();

Thread.Sleep(200);

//提高性能整体速度,原因不详

privatevoidtbSocketPort_TextChanged(objectsender,EventArgse)

if(this.tbSocketPort.Text!

="

this.btnSocketStart.Enabled=true;

//下面为一些界面处理函数

privatevoidbtnSocketStop_Click(objectsender,EventArgse)

Form1.SocketServiceFlag=false;

this.btnSocketStop.Enabled=false;

publicvoidaddUser(stringusername)

this.rtbSocketMsg.AppendText(username+"

已经加入\n"

//将刚连接的用户名加入到当前在线用户列表中

this.lbSocketClients.Items.Add(username);

this.tbSocketClientsNum.Text=System.Convert.ToString(clients.Count);

publicvoidremoveUser(stringusername)

已经离开\n"

//将刚连接的用户名加入到当前在线用户列表中

this.lbSocketClients.Items.Remove(username);

publicstringGetUserList()

stringRtn="

for(inti=0;

i<

lbSocketClients.Items.Count;

i++)

Rtn+=lbSocketClients.Items[i].ToString()+"

|"

returnRtn;

publicvoidupdateUI(stringmsg)

this.rtbSocketMsg.AppendText(msg+"

privatevoidForm1_FormClosing(objectsender,FormClosingEventArgse)

//下面为Client类定义

publicclassClient

privatestringname;

//保存用户名

privateSocketcurrentSocket=null;

//保存与当前用户连接的Socket对象

privatestringipAddress;

//保存用户的IP地址

privateForm1server;

//保存当前连接状态

//Closed--connected--closed

privatestringstate="

closed"

publicClient(Form1server,SocketclientSocket)

this.server=server;

this.currentSocket=clientSocket;

ipAddress=getRemoteIPAddress();

publicstringName

get

returnname;

set

name=value;

publicSocketCurrentSocket

returncurrentSocket;

//ipAddress

privatestringgetRemoteIPAddress()

return((IPEndPoint)currentSocket.RemoteEndPoint).Address.ToString();

//SendToClient()方法实现了向客户端发送命令请求的功能

privatevoidSendToClient(Clientclient,stringmsg)

System.Byte[]message=System.Text.Encoding.Default.GetBytes(msg.ToCharArray());

client.currentSocket.Send(message,message.Length,0);

//ServiceClient方法用于和客户端进行数据通信,包括接收客户端的请求

//它根据不同的请求命令执行相应的操作,并将处理结果返回到客户端

//ServiceClient()函数为服务器接收客户数据的线程主体,主要用来接收用户发送来的数据,并处理聊天命令

publicvoidServiceClient()

string[]tokens=null;

byte[]buff=newbyte[1024];

boolkeepConnect=true;

//用循环来不断地与客户端进行交互,直到客户端发出“EXIT”命令

//将keepConnect职为false,退出循环,关闭连接,并中止当前线程

while(keepConnect&

&

Form1.SocketServiceFlag)

//tokens=null;

if(currentSocket==null||currentSocket.Available<

Thread.Sleep(300);

continue;

//接收数据并存入BUFF数组中

intlen=currentSocket.Receive(buff);

//将字符数组转化为字符串

stringclientCommand=System.Text.Encoding.Default.GetString(buff,0,len);

//tokens【0】中保存了命令标志符(CONNCHATPRIVLIST或EXIT)

tokens=clientCommand.Split(newchar[]{'

|'

});

if(tokens==null)

catch(Exceptione)

server.updateUI("

发送异常:

+e.ToString());

//以上代码主要用于服务器初始化和接收客户端发送来的数据。

它在对用户数据进行解析后,把用户命令转换为数组方式。

if(tokens[0]=="

CONN"

//此时接收到的命令格式化为命令标识符CONN|发送者的用户名|tokens[1]中保存了发送者的用户名

this.name=tokens[1];

if(Form1.clients.Contains(this.name))

SendToClient(this,"

ERR|User"

+this.name+"

已经存在"

HashtablesyncClients=Hashtable.Synchronized(Form1.clients);

syncClients.Add(this.name,this);

//更新界面

server.addUser(this.name);

//对每一个当前在线的用户发送JOIN消息命令和LIST消息命令,以此来跟新客户端的当前在线用户列表

System.Collections.IEnumeratormyEnumerator=Form1.clients.Values.GetEnumerator();

while(myEnumerator.MoveNext())

Clientclient=(Client)myEnumerator.Current;

SendToClient(client,"

JOIN|"

+tokens[1]+"

Thread.Sleep(100);

//更新状态

state="

connected"

OK"

//向客户端发送LIST命令,以此更新客户端的当前在线用户列表

stringmsgUsers="

LIST|"

+server.GetUserList();

SendToClient(this,msgUsers);

elseif(tokens[0]=="

CHAT"

if(state=="

//此时收到的命令的格式为:

命令标识符CHAT|发送者的用户名:

发送内容|向所有当前在线的用户转发此信息

//将发送者的用户名:

发送内容转发给用户

SendToClient(client,tokens[1]);

server.updateUI(tokens[1]);

//senderrtoserver

ERR|stateerror,pleaseloginfirst"

PRIV"

命令标识符PRIV|发送者的用户名:

发送内容|

//tokens[1]中保存了发生者的用户名

stringsender=tokens[1];

//tokens[2]中保存了发送者的用户名

stringreceiver=tokens[2];

//tokens[3]中保存了发送的内容

stringcontent=tokens[3];

stringmessage=sender+"

-->

+receiver+”:

”+content;

//仅将信息转发给法送者和接收者

if(Form1.clients.Contains(sender))

SendToClient((Client)Form1.clients[sender],message);

if(Form1.clients.Contains(receiver))

SendToClient((Client)Form1.clients[receiver],message);

EXIT"

{//此时收到的命令的格式为:

命令标识符EXIT|发送者的用户名:

//向所有当前在线的用户发送该用户已离开的消息

if(Form1.clients.Contains(tokens[1]))

Clientclient=(Client)Form1.clients(tokens[1]));

//将该用户对应Client对象从clients中删除

syncClients.Remove(client.name);

server.removeUser(client.name);

//向客户端发送QUIT命令

stringmessage="

QUIT|"

+tokens[1]

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

当前位置:首页 > 医药卫生 > 基础医学

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2