ch1.3.2スロットプログラミング(TCPサーバ、クライアント)


TCPサーバ
package test;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;

public class TCPServer {

	public static void main(String[] args) {
		ServerSocket serverSocket = null;
		try {// 서버소켓에대한 익셉션
				// 1. 서버소켓 생성
			serverSocket = new ServerSocket();
			// 2. 바인딩(binding)
			// Socket에 InetSocketAddress(IPAddress + port가 있음)
			// IPAdress : 0.0.0.0 : 모든 IP로 부터의 연결을 허용 ( 호스트 IP가 바뀔 수 있기때문에 특정IP바인딩하기보단
			// 0.0.0.0
			serverSocket.bind(new InetSocketAddress("0.0.0.0", 5000));

			// 3. accept
			// 클라이언트로 부터 연결 요청을 기다린다.
			Socket socket = serverSocket.accept();// blocking 돼어서 연결안됨 xshell에서 telnet 127.0.0.1 포트번호(5000) 입력
			// 연결된 클라이언트 IP주소 얻기
			InetSocketAddress inetRemoteSocketAddress = (InetSocketAddress) socket.getRemoteSocketAddress(); // ,포트 까지
																												// 필요할때
																												// 다운캐스팅
			String remoteHostAddress = inetRemoteSocketAddress.getAddress().getHostAddress();
			int remoteHostPort = inetRemoteSocketAddress.getPort();
			System.out.println("[server] connected by client[" + remoteHostAddress + ":" + remoteHostPort + "]");	// TCPClient 컴파일시 cmd창에  출력

			try { // 데이터통신 IO에대한 익셉션
				// 4. IO Stream 받아오기
				InputStream is = socket.getInputStream();
				OutputStream os = socket.getOutputStream();

				while (true) {
					// 5. 데이터 읽기
					byte[] buffer = new byte[256];
					int readByteCount = is.read(buffer); // blocking
					if (readByteCount == -1) {
						// 반대편(클라이언트)가 정상적으로 종료(close() 호출)
						System.out.println("[server] closed by Client");
						break;
					}

					String data = new String(buffer, 0, readByteCount, "utf-8");
					System.out.println("[server] received:" + data);
					
					//6. 데이터 쓰기
					os.write(data.getBytes("utf-8"));
					
				}
			} catch (SocketException e) {
				System.out.println("[server] suddenly closed by client" + e);
			} catch (IOException e) { // 데이터통신 io 익셉션
				System.out.println("[server] error" + e);
			} finally {
				try {
					if (socket != null && socket.isClosed() == false) {
						socket.close();
					}
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		} catch (IOException e) { // 서버소켓관련 io익셉션
			System.out.println("[server] error : " + e);
		} finally {
			try {
				if (serverSocket != null && serverSocket.isClosed() == false) {
					serverSocket.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

}
TCPクライアント
package test;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketException;

public class TCPClient {
	private static final String SERVER_IP = "127.0.0.1";
	private static final int SERVER_PORT = 5000;
	
	public static void main(String[] args) {
		Socket socket =null;
		try {
			//1. 소켓 생성
			socket = new Socket();
			//2. 서버 연결
			socket.connect(new InetSocketAddress(SERVER_IP,SERVER_PORT));
			
			// 3. IO Stream 받아오기
			InputStream is = socket.getInputStream();
			OutputStream os = socket.getOutputStream();

			// 4. 쓰기
			String data = "Hello World";
			os.write(data.getBytes("UTF-8"));//엔코딩
			
			//5. 읽기
			byte[] buffer = new byte[256];
			int readByteCount = is.read(buffer); // blocking
			if (readByteCount == -1) {
				// 반대편(클라이언트)가 정상적으로 종료(close() 호출)
				System.out.println("[Client] closed by server");
			}
			
			data = new String(buffer, 0, readByteCount, "UTF-8");
			System.out.println("[client] received:" + data);
			
		} catch (SocketException e) {
			System.out.println("[client] suddenly close by server : " + e);
		} catch (IOException e) {
			System.out.println("[client] error : " + e);
		}finally {
			try {
				if (socket != null && socket.isClosed() == false) {
					socket.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

}
経済サーバ
package echo;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;

public class EchoServer {
	private static final int PORT = 6000;

	public static void main(String[] args) {

		ServerSocket serverSocket = null;

		try {
			serverSocket = new ServerSocket();

			serverSocket.bind(new InetSocketAddress("0.0.0.0", PORT)); // 소켓에다 소켓어드레스(ip어드레스 + 포트번호) 바인딩
			log("starts... [port:" + PORT + "]");

			Socket socket = serverSocket.accept();
			
			InetSocketAddress inetRemoteSocketAddress = (InetSocketAddress) socket.getRemoteSocketAddress(); // ,포트 까지// 필요할때다운캐스팅
			String remoteHostAddress = inetRemoteSocketAddress.getAddress().getHostAddress();
			int remoteHostPort = inetRemoteSocketAddress.getPort();
			log("connected by client[" + remoteHostAddress + ":" + remoteHostPort + "]");

			try {
				BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream(), "UTF-8"));// 개행붙여오는애들 받는것
				PrintWriter pw = new PrintWriter(new OutputStreamWriter(socket.getOutputStream(), "UTF-8"), true);// true 넣으면 자동 fflush 개행 붙여서 보내는것

				while (true) {
					String data = br.readLine();
					if (data == null) {
						log("closed by client");
						break;
					}

					log("received:" + data);
					pw.println(data);
				}
			} catch (IOException e) {
				log("error:" + e);
			} finally {
				try {
					if (socket != null && socket.isClosed() == false) {
						socket.close();
					}
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		} catch (IOException e) {
			log("error: " + e);
		} finally {
			try {
				if (serverSocket != null && serverSocket.isClosed() == false) {
					serverSocket.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
	public static void log(String log) {
		System.out.println("[EchoServer] " + log);
	}
}
エコノミークライアント
package echo;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketException;
import java.util.Scanner;

public class EchoClient {

	private static final String SERVER_IP = "127.0.0.1";
	private static final int SERVER_PORT = 6000;
	public static void main(String[] args) {
		Socket socket = null;
		Scanner scanner = null;
		try {
			scanner = new Scanner(System.in);
			
			socket = new Socket();
			
			socket.connect(new InetSocketAddress(SERVER_IP, SERVER_PORT));
			log("connected");
			
			BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream(), "UTF-8"));// 개행붙여오는애들 받는것
			PrintWriter pw = new PrintWriter(new OutputStreamWriter(socket.getOutputStream(), "UTF-8"), true);// true 넣으면 자동 fflush 개행 붙여서 보내는것
			
			while(true) {
				System.out.print(">");
				String line = scanner.nextLine();
				
				if("exit".equals(line)){
					break;
				}
				
				pw.println(line); // 스캐너로 입력할때 개행이 입력안되므로 보내주는것
				
				String data = br.readLine();
				if(data == null) {
					log("closed by server");
					break;
				}
				System.out.println("<" + data);
			}
		}catch(SocketException e) {
			log("suddenly closed by server");
		}catch(IOException e) {
			log("error:" + e);
		}finally {
			try {
				if(scanner != null) {
					scanner.close();
				}
				if(socket != null && socket.isClosed() == false) {
					socket.close();					
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
	private static void log(String log) {
		System.out.println("[Echo Client] " + log);
	}
}