マルチユーザーチャットルームのTCPシミュレーションを持つJavaネットワークプログラミング

Javaのネットワークは、チャットルームを使用してTCPシミュレーションプログラミング

Shangxue唐チー高校教師のJavaに沿って、最近のB駅では、コースでは、知識の話ばかり教師、非常に良いではない、もっと重要なのは、アイデアを話すに関与している、学ぶために皆をお勧めします!
B駅ポータル:にポイント私
のTCPの基本的な手順の簡単なシミュレーションのブログ上のJava
これは完全に前の知識に拡張されます
:多人数チャットルーム機能
1.複数のクライアントが同時にチャットすることができます
2。ユーザー名を入力するようにクライアントをカスタマイズすることができ
、クライアントは他のメッセージングクライアントが受け取るかもしれ3.
こんにちはZhangsan:個人@Zhangsanに相談する4を!

まず、機能要件の簡単な分析、ビューの一点
1.複数のクライアントがマルチスレッドに使用しなければならない、とクライアントは、同時に<&&メッセージを受け入れるためのメッセージを送信する>ことができます。
各クライアントクラスの文字列名を作成します。2.、あなたはコンソールから入力することができます。
3. Aクライアントとサーバの通信は、第1パイプライン、我々は配列に格納されているパイプラインを構築する際に、髪の端部に対応する顧客へのパイプラインを介して、再びパイプラインを通過する必要がある他のクライアントへのメッセージメッセージは、することができます。
4.サーバーがクライアントから送信されたメッセージを受信すると、の解剖をしましょう。ウィスパー形式:@ユーザー名:行に、我々は、ユーザー名とメッセージの内容を抽出し、メッセージの内容、この形式を満たしていない文字を見て、パイプラインのトラバースは彼にメッセージを与えるためにパイプラインに対応するユーザ名を見つけます。ウィスパーフォーマットは、その後、我々はポイント3に沿って、作られているすべての人にデフォルト設定され、準拠していません。

サーバー

ストレージパイプラインの時間、同時に読み書きのアカウントに複数のクライアントを取って
、CopyOnWriteArrayListとの使用を検討し、底は配列array揮発性過渡声明で、個別の読み取りおよび書き込みを実現するために、コピー・オン・ライトの新しい配列、挿入を完了し、新しいアレイのアレイに割り当てられた操作の後に変更または削除。

CopyOnWriteArrayList<mxy> all=new CopyOnWriteArrayList<mxy>();   //用来存储管道们

接続を確立します

ServerSocket server=new ServerSocket(5655); 

私は、クライアントの接続を受け入れることを聞いて停止するようになりました

while(true){
		Socket client=server.accept();		//时刻准备着客户端们!
		mxy dog=new mxy(client);
		all.add(dog); 						//容器管理所有的客户端
		new Thread(dog).start();			//实现能够同时接受、发送的多线程
	}

マルチスレッドクラスを送受信

 class mxy implements Runnable{

	private Socket client;
	private DataInputStream dis;
	private DataOutputStream dos;
	private String namee;
	public mxy(Socket client) throws IOException {
		// TODO Auto-generated constructor stub
		this.client=client;
		try {
			dis=new DataInputStream(client.getInputStream()); 
			dos=new DataOutputStream(client.getOutputStream());
			
			//先获取输入的用户名 用于下一步操作
			namee=dis.readUTF(); 

			//发送XX来了到别的客户端
			for(mxy other:all) {
				if(other.equals(this)) {//如果是客户端时自己的话就不重复发送了
					continue;
				}
				else {
					other.dos.writeUTF(namee+"进入了聊天室!");
				}
			 }
			
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			//释放资源
			dis.close();
			dos.close();
			client.close();
		}
	}
	
	@Override
	public void run() {
		// TODO Auto-generated method stub
		boolean flag=true;
		while(flag)
		{
			String datas = null;			//存储整个一条消息
			String[] siliaodata=null;		//存储私聊内容
			String[] siliaouser=null;		//存储私聊用户名
			try {
				datas = dis.readUTF();
				//System.out.println(datas.charAt(0));
				
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
				//释放资源
				try {
					dis.close();
				} catch (IOException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}
				try {
					dos.close();
				} catch (IOException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}
				try {
					client.close();
				} catch (IOException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}
			}
			
			
			try {
				//开始判断是不是私聊,是的话-----------------------------------------
				if(datas.charAt(0)=='@')
				{
					siliaodata=datas.split(":");			//用spilt分割冒号
					siliaouser=siliaodata[0].split("@");	//用spilt分割@
					for(mxy other:all) {					//遍历客户端开始寻找
						if(other.namee.equals(siliaouser[1])) {	
							other.dos.writeUTF(namee+"对你说"+siliaodata[1]);//开始给私聊的客户端发送消息
						}
					}
				}
				//下面是不是的话,代表给全体发的-------------------------------------
				else {
					for(mxy other:all) {
						if(other.equals(this)) {
							continue;
						}
						else {
							other.dos.writeUTF(namee+"对所有人说"+datas);
						}
					 }
				
				}
				//--------------------------------------------------------------
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
				//释放资源
				try {
					dis.close();
				} catch (IOException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}
				try {
					dos.close();
				} catch (IOException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}
				try {
					client.close();
				} catch (IOException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}
			}
		}
	}
	
}

クライアントの
ユーザー名がユーザー名DataOutputStreamの最初のパスで最初に渡す方法でもあるときに、クライアントは、必要が複数のスレッドを使用して受信し、送信メッセージを達成するために、各クライアントは、新しいクラスが送信されるユーザー名を入力する必要があります他のヒントへのクライアントのためにサーバに:XXXは、チャットルームを入力してください。その他には何もありません

接続を確立します

Socket client=new Socket("localhost",5655);
public class Client {
	static String namee;
	static Scanner sc=new Scanner(System.in);
	public static void main(String[] args) throws Exception, IOException {
		Socket client=new Socket("localhost",5655);
		System.out.println("请输入您的名字");
		namee=sc.next();
		new Thread(new Send(client,namee)).start();	     //在Send构造器里传进去用户名
		new Thread(new Receive(client)).start();
	//	client.close();  这句该死的代码!错了一晚上,不能把客户端关掉!
	}

クラス送る
他のクライアントに配布サーバ側を読み出し、コンストラクタ、で失われたユーザの名を作成するために送信します

class Send implements Runnable{
		Scanner sc=new Scanner(System.in);
		private DataOutputStream dos;
		private Socket client;
		private String namee;
		public Send(Socket client, String namee) {
			this.namee=namee;
			this.client=client;
			try {
				dos=new DataOutputStream(client.getOutputStream());
				dos.writeUTF(namee);       //先通过管道把用户名丢进去 用于提示XXX进入了聊天室
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}	
		}
		@Override
		public void run() {
			// TODO Auto-generated method stub
			boolean flag=true;	
			while(flag)
			{
				String msg;
				msg=sc.next();				  //键盘读入要发送的信息
				try {
					dos.writeUTF(msg);           
					dos.flush();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
					try {
						dos.close();
					} catch (IOException e1) {
						// TODO Auto-generated catch block
						e1.printStackTrace();
					}
				}
			}
		}
	}

受付クラスは
、と前と同じように何も言うことはありません

 class Receive implements Runnable{
		private DataInputStream dis;
		private Socket client;
		private String namee;
		public Receive(Socket client) {
			this.client=client;
			try {
				dis=new DataInputStream(client.getInputStream());
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
				//释放资源
				try {
					dis.close();
				} catch (IOException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}
				try {
					client.close();
				} catch (IOException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}
			}
		}	
		@Override
		public void run() {
		boolean flag=true;	
		while(flag)
		{
			try {
				String res=dis.readUTF();
				System.out.println(res);
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
				try {
					dis.close();
				} catch (IOException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}
			}
		}
	}
}

コードレンダリング:ここに画像を挿入説明
私はIOストリーム、カプセル化リソース解放方法を入れていなかった、それは混乱のビットが、実際には、真実が同じであるように見えるかもしれませんが、また、あなたが私を許し願っています!
間違った場所ならば、コメント欄に正しい私に歓迎!

リリース3元の記事 ウォンの賞賛0 ビュー92

おすすめ

転載: blog.csdn.net/weixin_43416532/article/details/104137762