TCP Socketプログラミング--チャットの雛形


久しぶりにjavaeyeブログを书いて、最近TCP Socketプログラミングを书いて、みんなと分かち合います!
チャットの原理:TCPサービス端を起動して、クライアントの接続を待って、クライアントがサービス端に接続した後に、サービス端は1つのスレッドを作成してこのクライアントに対して読み書きを行って、サービス端は引き続き指定のポートでクライアントの接続を傍受します.クライアント接続に成功したら、サーバ側と通信するために書き込みスレッドと読み取りスレッドを作成します.サーバ側スレッドはクライアントの情報を受信し,その情報をメッセージの宛先クライアントに転送する.宛先クライアントは,送信スレッドを介してサーバ側にメッセージを送信し,サーバ側はメッセージを受信し,宛先クライアントにメッセージを転送する.サーバ側スレッドはクライアントに自発的にメッセージを送信するのではなく,サーバ側スレッドは中継クライアントから送られてきた情報を指定した宛先クライアントに送信するだけである.
クライアントAからクライアントBにメッセージを送信する方法
1、クライアントAは書き込みスレッドを通じて、メッセージをサーバー側に書き込む
2、サーバー側はクライアントAのメッセージを受信し、メッセージの内容を解析し、メッセージがクライアントBに送信されることを知り、サーバー側スレッドはメッセージをクライアントBに書き込む
3、クライアントBがスレッドを読み取ってサーバスレッドから送られてきたデータを読み取る
これにより、クライアントAからクライアントBへのメッセージの送信が完了し、クライアントBを介しても同様にクライアントAへのメッセージの送信が行われる.双方向通信を完了します.
 
サービス:
package com.guchao.chat;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

public class TCPServer {

	private Map<String, Socket> sockets = new HashMap<String, Socket>();
	
	/**
	 * @param args
	 * @throws IOException 
	 */
	public static void main(String[] args) throws IOException {
			new TCPServer().go();
	}
	
	public void go(){
		ServerSocket ss = null;
		try {
			ss = new ServerSocket(8888);
			System.out.println("       , 8888        !");
		} catch (IOException e1) {
			e1.printStackTrace();
		}
		Socket s = null;
		int i = 0;
		while(true){
			try {
				s = ss.accept();
				String clientName = "Client_"+(++i);
				sockets.put(clientName, s);
				sendMessageToOtherClients(clientName);
				System.out.println(clientName+"      !");
			} catch (IOException e) {
				e.printStackTrace();
			}
			
			ReadAndWriteThread t = new ReadAndWriteThread(s);
			new Thread(t).start();
		}
	}
	
	private void sendMessageToOtherClients(String clientName) {
		if(sockets != null && sockets.size() > 0){
			for (Iterator<String> iterator = sockets.keySet().iterator(); iterator.hasNext();) {
				String key = (String) iterator.next();
				Socket s = sockets.get(key);
				try {
					DataOutputStream dos = new DataOutputStream(s.getOutputStream());
					dos.writeUTF(clientName+"        !");
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}
	
	class ReadAndWriteThread implements Runnable{
		private DataInputStream dis = null;
		
		public ReadAndWriteThread(Socket s){
			try {
				dis = new DataInputStream(s.getInputStream());
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		
		@Override
		public void run() {
			String str = "";
			while(true){
				try {
					/**
					 *        hello,jjkdfjaf*     *
					 *   :hello,zhangsan*Client_2*
					 *     hello,zhangsan   Client_2
					 */
					str = dis.readUTF();
					if("bye".equals(str))
						break;
					sendMessageToClient(str);
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}
	
	private void sendMessageToClient(String str){
		int startPosition = str.lastIndexOf("*", str.lastIndexOf("*")-1);
		int endPosition = str.lastIndexOf("*");
		if(startPosition > 0 && endPosition > 0 && endPosition > startPosition){
			String clientName = str.substring(startPosition+1, endPosition);
			Socket s = sockets.get(clientName);
			DataOutputStream dos = null;
			try {
				if(s != null){
					dos = new DataOutputStream(s.getOutputStream());
					dos.writeUTF(str);
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
}

 
クライアント:
package com.guchao.chat;

import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;
import java.net.UnknownHostException;

public class TCPClient {

		public static void main(String[] args) throws UnknownHostException, IOException{
			new TCPClient().go();
		}
		
		public void go() {
			try {
				Socket s = new Socket("127.0.0.1",8888);
//				     , socket     
				RecvThread recv = new RecvThread(s);
				new Thread(recv).start();
				
//				     ,     socket 
				SendThread send = new SendThread(s);
				new Thread(send).start();
			} catch (UnknownHostException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}

		class RecvThread implements Runnable{
			private DataInputStream dis = null;
			
			public RecvThread(Socket s){
				try {
					dis = new DataInputStream(s.getInputStream());
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			
			@Override
			public void run() {
				String str = "";
				while(true){
					try {
						// socket     
						str = dis.readUTF();
						if("bye".equals(str))
							break;
						System.out.println("received message:"+str);
					} catch (IOException e) {
						e.printStackTrace();
					}
				}
			}
		}
		
		class SendThread implements Runnable{
			private DataOutputStream dos;
			
			public SendThread(Socket s){
				try {
					dos = new DataOutputStream(s.getOutputStream());
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			
			@Override
			public void run() {
				String str = "";
				while(true){
					System.out.println("input message:");
					BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
					try {
						str = br.readLine();
//						     socket 
						dos.writeUTF(str);
						if("bye".equals(str))
							break;
					} catch (IOException e) {
						e.printStackTrace();
					}
				}
			}
		}
}