public void addUser(string username) { msg_Handle msg = new msg_Handle(this.rtbSocketMsg.AppendText); if (this.rtbSocketMsg.InvokeRequired) this.rtbSocketMsg.Invoke(msg, new object[] { username + " 已经加入\n" }); else this.rtbSocketMsg.AppendText(username + " 已经加入\n");//追加文本 //将刚连接的用户名加入到当前在线用户列表中 Username[clients.Count]=username; //Count++; }
//在新的线程中的操作,它主要用于当接收到一个客户端请求时,确认与客户端的连接, //并且立刻启动一个新的线程来处理和该客户端的信息交互。 private void StartSocketListen() { while (Form1.SocketServiceFlag) { try { //当接收到一个客户端请求时,确认与客户端的连接 if (listener.Pending())//检查是否连接请求,如果有则为True { Socket socket = listener.AcceptSocket(); if (clients.Count >= MAX_NUM) { //msg_Handle msg_Handle1 = new msg_Handle(this.rtbSocketMsg.AppendText); //this.rtbSocketMsg.Invoke(msg_Handle1, new object[]{"已经达到了最大连接数:" + // MAX_NUM + ",拒绝新的连接\n"}); ////this.rtbSocketMsg.AppendText("已经达到了最大连接数:" + //// MAX_NUM + ",拒绝新的连接\n"); socket.Close(); } else { //启动一个新的线程, //执行方法this.ServiceClient,处理用户相应的请求 Client client = new Client(this, socket); Thread clientService = new Thread( new ThreadStart(client.ServiceClient)); clientService.Start(); AutoRead(client); //client.ReadFromBuffer_ServerToOutside(); } } Thread.Sleep(200);//主线程休息200ms } catch (Exception ex) { msg_Handle msg_Handle2 = new msg_Handle(this.rtbSocketMsg.AppendText); this.rtbSocketMsg.Invoke(msg_Handle2, new object[] { ex.Message.ToString() + "\n" }); } } }
//ServiceClient方法用于和客户端进行数据通信,包括接收客户端的请求, //根据不同的请求命令,执行相应的操作,并将处理结果返回到客户端 public void ServiceClient() { string[] tokens = null; byte[] buff = new byte[1024];//可以改动 bool keepConnect = true; msg_Handle msg_Handle = new msg_Handle(this.server.updateUI); //用循环来不断地与客户端进行交互,直到客户端发出“EXIT”命令, //将keepConnect置为false,退出循环,关闭连接,并中止当前线程 while (keepConnect && Form1.SocketServiceFlag) { tokens = null; try { if (currentSocket == null || currentSocket.Available < 1) { Thread.Sleep(300); continue; } //接收数据并存入buff数组中 int len = currentSocket.Receive(buff); //buff.CopyTo(buffer, 0); //将字符数组转化为字符串 string clientCommand = System.Text.Encoding.Unicode.GetString( buff, 0, len); //server.updateUI(clientCommand); this.server.rtbSocketMsg.Invoke(msg_Handle, new object[] { clientCommand }); // server.rtbSocketMsg.Invoke(new msg_Handle(this.server.updateUI), new object[] { clientCommand }); // msg_Handle msg_Handle=ne //tokens[0]中保存了命令标志符(CONN、CHAT、PRIV、LIST或EXIT) tokens = clientCommand.Split(new Char[] { '|' }); if (tokens == null) { Thread.Sleep(200); continue; } } catch (Exception e) { //server.updateUI("发生异常:"+ e.ToString()); this.server.rtbSocketMsg.Invoke(msg_Handle, new object[] { "发生异常:" + 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 + " 已经存在"); } else { Hashtable syncClients = Hashtable.Synchronized( Form1.clients); syncClients.Add(this.name, this); server.addUser(this.name); //server.rtbSocketMsg.Invoke(new msg_Handle(this.server.updateUI), new object[] { "发生异常:" + e.ToString() }); //对每一个当前在线的用户发送JOIN消息命令和LIST消息命令, //以此来更新客户端的当前在线用户列表 System.Collections.IEnumerator myEnumerator = Form1.clients.Values.GetEnumerator(); while (myEnumerator.MoveNext()) { Client client = (Client)myEnumerator.Current; //string msg = CreateFrame("JOIN", tokens[1]).ToString(); //SendToClient(client,"JOIN", msg); SendToClient(client, "JOIN|" + tokens[1] + "|"); Thread.Sleep(100); } //更新状态 state = "connected"; //SendToClient(this, "ok"); //向客户端发送LIST命令,以此更新客户端的当前在线用户列表 //string msgUsers= CreateFrame("LIST", server.GetUserList()).ToString(); //SendToClient(this, "LIST",msgUsers); string msgUsers = "LIST|" + server.GetUserList(); SendToClient(this, msgUsers); /********************************************************/ } } else if (tokens[0] == "LIST") { if (state == "connnected") { //向客户端发送LIST命令,以此更新客户端的当前在线用户列表 //string msgUsers = CreateFrame("LIST", server.GetUserList()).ToString(); //SendToClient(this, "LIST",msgUsers); string msgUsers = "LIST|" + server.GetUserList(); SendToClient(this, msgUsers); } else { //send err to server //string msg = CreateFrame("ERR", "state error,Please login first").ToString(); //SendToClient(this,"ERR", msg); SendToClient(this, "ERR|state error,Please login first"); } } else if (tokens[0] == "PRIV") { if (state == "connected") { //此时接收到的命令格式为: //命令标志符(PRIV)|发送者用户名|接收者用户名|发送内容| //tokens[1]中保存了发送者的用户名 string sender = tokens[1]; //tokens[2]中保存了接收者的用户名 string receiver = tokens[2]; //tokens[3]中保存了发送的内容 string content = tokens[3]; string msg = System.Text.Encoding.Unicode.GetString(CreateFrame("PRIV", tokens[1], tokens[2], tokens[3])); //将发送信息存入缓存中,格式为“sender to receiver:message” WriteToBuffer_ServerToOutside(System.Text.Encoding.Unicode.GetBytes(tokens[1] + " to " + tokens[2] + " : " + tokens[3])); //仅将信息转发给发送者和接收者 if (Form1.clients.Contains(sender)) { //SendToClient( // (Client)ClientSeverForm.clients[sender], msg); SendToClient( (Client)Form1.clients[sender], "单发成功!|"); } if (Form1.clients.Contains(receiver)) { SendToClient( (Client)Form1.clients[receiver], msg); } } else { SendToClient(this, "ERR|state error,Please login first"); } } else if (tokens[0] == "EXIT") { //此时接收到的命令的格式为:命令标志符(EXIT)|发送者的用户名 //向所有当前在线的用户发送该用户已离开的信息 if (Form1.clients.Contains(tokens[1])) { Client client = (Client)Form1.clients[tokens[1]]; //将该用户对应的Client对象从clients中删除 Hashtable syncClients = Hashtable.Synchronized( Form1.clients); syncClients.Remove(client.name); server.removeUser(client.name); //向客户端发送QUIT命令 //string msg = CreateFrame("QUIT", tokens[1]).ToString(); string message = "QUIT|" + tokens[1]; System.Collections.IEnumerator myEnumerator = Form1.clients.Values.GetEnumerator(); while (myEnumerator.MoveNext()) { Client c = (Client)myEnumerator.Current; //if(c.name!=this.name) //SendToClient(c,"QUIT", msg); SendToClient(c, message); // else // SendToClient(c, "成功退出!"); } } //退出当前线程 break; } Thread.Sleep(100); } }