[クレイジーJava]TCP:プロトコル文字、クライアント情報の記録


1.ここでは、TCP通信の一般的な技術を一例として説明する.
1)一般的には、赤ドリル、黄ドリル、プライベートチャット、グループチャットなど、双方の通信ルールをカスタマイズする必要があります.
2)このような規則はパケットの中でプロトコル文字で表さなければならない.プロトコル文字はカスタマイズされ、通信双方の交流の約束である.
3)通常、サーバはクライアントの情報を記録する必要があり、例えばログイン情報など、クライアントが要求を送信する際にこれらの情報を一括して送信する必要があり、サーバ側は抽出して保存することができる.
2.例:
プロトコル文字:
package com.lirx;

public interface Protocol {
	int PROTOCOL_LEN = 2; //        
	
	//                
	String MSG_ROUND = "§γ"; //         
	String USER_ROUND = "∏∑"; //        
	String PRIVATE_ROUND = "★【"; //         
	String SPLIT_SIGN = "※"; //    
	
	//         (      )
	String LOGIN_SUCCESS = "1"; //     
	String NAME_REP = "-1"; //     
}
サーバ:
package com.lirx.server;

import java.io.IOException;
import java.io.PrintStream;
import java.net.ServerSocket;
import java.net.Socket;

import com.lirx.map.MyMap;

public class Server {
	private static final int SERVER_PORT = 30000;
	
	private MyMap<String, PrintStream> clientsPsMap = new MyMap<>();
	
	public void init() {
		try (ServerSocket ss = new ServerSocket(SERVER_PORT)) {
			while (true) {
				Socket s = ss.accept();
				new ServerThread(s, clientsPsMap).start();
			}
		}
		catch (IOException e) {
			System.out.println("       !    " + SERVER_PORT + "   ?");
		}
	}
	
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		new Server().init();
	}

}
package com.lirx.server;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.Socket;

import com.lirx.Protocol;
import com.lirx.map.MyMap;

public class ServerThread extends Thread {
	private Socket s;
	private MyMap<String, PrintStream> map;
	
	public ServerThread(Socket s, MyMap<String, PrintStream> map) {
		this.s = s;
		this.map = map;
	}

	private String getContent(String line) { //           
		return line.substring(Protocol.PROTOCOL_LEN,
				line.length() - Protocol.PROTOCOL_LEN);
	}
	
	@Override
	public void run() {
		// TODO Auto-generated method stub
		// super.run();
		
		try {
			BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
			PrintStream ps = new PrintStream(s.getOutputStream());
			
			String line = "";
			while ((line = br.readLine()) != null) {
				if (line.startsWith(Protocol.USER_ROUND) && //     
					line.endsWith(Protocol.USER_ROUND)) {
					String userName = getContent(line);
					if (map.containsKey(userName)) {
						System.out.println(userName + "    ");
						ps.println(Protocol.NAME_REP);
					}
					else {
						System.out.println(userName + "    ");
						ps.println(Protocol.LOGIN_SUCCESS);
						map.put(userName, ps);
					}
				}
				else if (line.startsWith(Protocol.PRIVATE_ROUND) &&
						 line.endsWith(Protocol.PRIVATE_ROUND)) { //     
					String tarAndMsg = getContent(line);
					String[] split = tarAndMsg.split(Protocol.SPLIT_SIGN);
					String tar = split[0];
					String msg = split[1];
					map.get(tar).println(map.getKeyByValue(ps) + "     :" + msg);
				}
				else { //     
					String msg = getContent(line);
					for (PrintStream eachPs: map.valueSet()) {
						eachPs.println(map.getKeyByValue(ps) + " :" + msg);
					}
				}
			}
		}
		catch (Exception e) {
			e.printStackTrace();
		}
	}
	
}
クライアント:
package com.lirx.client;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.Socket;

import javax.swing.JOptionPane;

import com.lirx.Protocol;

public class Client {

	private final static int SERVER_PORT = 30000;

	private Socket s;
	private PrintStream ps;
	private BufferedReader br;
	private BufferedReader keyIn;

	public void init() {
		try {
			s = new Socket("127.0.0.1", SERVER_PORT);
			ps = new PrintStream(s.getOutputStream());
			br = new BufferedReader(new InputStreamReader(s.getInputStream()));
			keyIn = new BufferedReader(new InputStreamReader(System.in));

			String tip = "";
			while (true) { //                 
				String name = JOptionPane.showInputDialog(tip + "     ");
				ps.println(Protocol.USER_ROUND + name + Protocol.USER_ROUND);
				String res = br.readLine();
				if (res.equals(Protocol.NAME_REP)) {
					tip = "    ";
					continue;
				}
				if (res.equals(Protocol.LOGIN_SUCCESS)) {
					break;
				}
				tip = "";
			}
		} catch (Exception e) {
			e.printStackTrace();
		}

		new ClientThread(br).start(); //                     ,           

		try { //                     
			String line = "";
			while ((line = keyIn.readLine()) != null) {
				if (line.indexOf(":") > 0 && line.startsWith("//")) { //     :   "//XXX:  "
					line = line.substring(2);
					String[] split = line.split(":");
					ps.println(Protocol.PRIVATE_ROUND + split[0] + Protocol.SPLIT_SIGN + split[1]
							+ Protocol.PRIVATE_ROUND);
				} else { //     
					ps.println(Protocol.MSG_ROUND + line + Protocol.MSG_ROUND);
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public static void main(String[] args) {
		new Client().init();
	}
}
package com.lirx.client;

import java.io.BufferedReader;
import java.io.IOException;

public class ClientThread extends Thread { //                       
	private BufferedReader br;
	
	public ClientThread(BufferedReader br) {
		this.br = br;
	}

	@Override
	public void run() {
		// TODO Auto-generated method stub
		// super.run();
		String line = "";
		try {
			while ((line = br.readLine()) != null) {
				System.out.println(line);
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		finally { //            
			if (br != null)
				try {
					br.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
		}
	}
	
	
}