🔶 이것이 자바다 : TCP 네트워킹(1)
✔ TCP 네트워킹(1)
💡 서버 와 클라이언트 연결하기
- 서버 코드
package ThisJavaRead; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.InetSocketAddress; import java.net.ServerSocket; import java.net.Socket; public class SeverSoket { public static void main(String[] args) { // 1) 서버 소켓변수 선언 ServerSocket serverSocket = null; // 2) 서버 소켓 객체 생성 => 예외가 발생할 수 있기 때문에 예외처리를 한다 try { serverSocket = new ServerSocket(); // 3) 포트와 바인드 => 현재 컴퓨터의 5001 번에 바인딩 한다는 뜻 serverSocket.bind(new InetSocketAddress("localhost",5001)); // 4) 무한루프 => 서버는 항상 클라이언트의 요청을 기다려야 하기 때문에 while(true) { System.out.println("[연결 기다림]"); // 5) 클라이언트 연결 요청 수락 => 클라이언트가 연결요청 하기 전까지는 대기상태 // 클라리언트로부터 연결요청이 왔을 때 accept는 soket이라는 통신용 객체를 생성하고 리턴한다 Socket socket = serverSocket.accept(); // Socket 을 가지고 클라이언트의 정보를 얻어 내거나 클라이언트와 데이터를 주고 받을 수 있다 // 6) 클라이언트의 아이피 출력하기 //(InetSocketAddress) : 타입변환 => getRemoteSocketAddress 가 SocketAddress를 // 리턴하기때문에 InetSocketAddress 으로 타입변환 해준다 InetSocketAddress isa = (InetSocketAddress) socket.getRemoteSocketAddress(); System.out.println("[연결 수락함]" + isa.getHostName()); // 8) 받은 데이터 저장할 byte배열 생성 byte[] bytes =null; // 9) 문자열로 변환해서 저장할 변수 선언 String message = null; // 10) 클라이언트가 보낸 데이터 받기 InputStream is = socket.getInputStream(); // 11) 길이 100 짜리 byte 배열생성 bytes = new byte[100]; // 12) 데이터 읽기 // is.read() : input stream으로부터 read메소드 불러오기 // is.read(bytes) : 매개값 => 바이트배열 // read() : 클라이언트가 데이터를 보내기 전 까지는 대기 상태이다 // 클라이언트가 데이터를 보내게 되면 배개값(bytes)에 저장되고 // 실제로 읽은 바이트 수는 변수 (readByteCount) 에 저장된다 int readByteCount = is.read(bytes); // 13) 문자열로 변환 => 1번 바이트 수만큼 변환,클라이언트가 utf-8로 바이트 배열을 만들었기 때문에 utf-8로 복원 message = new String(bytes,0,readByteCount, "UTF-8"); System.out.println("[데이터 받기 성공]" + message ); // 14) 서버가 클라이언트로 데이터 보내기 // 소켓으로부터 아웃풋스트림 얻기 OutputStream os = socket.getOutputStream(); // 보낼 메세지 작성 message = "Hello Client"; // 메세지로 부터 바이트 배열 얻기 bytes = message.getBytes("UTF-8"); // 아웃풋스트림 이용해 바이트 배열 출력 os.write(bytes); os.flush(); System.out.println("[데이터 보내기 성공]"); // 15) I/O 사용 안하기 때문에 전부 닫아주기 is.close(); os.close(); socket.close(); // 소켓을 닫는것 => 연결 끊기 } } catch (Exception e) { e.printStackTrace(); } // 7) 서버 소켓 닫기 // 만약에 서버소켓이 현재 닫혀있지 않다면 if(!serverSocket.isClosed()) { // 서버소켓을 닫아준다 , 예외처리 try { serverSocket.close(); } catch (IOException e) { e.printStackTrace(); } } } }
▶ 서버실행시 출력 콘솔
▶ 클라이언트 연결후 출력 콘솔
-
클라이언트 코드
package ThisJavaRead; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.InetSocketAddress; import java.net.Socket; public class Client { public static void main(String[] args) { // 1) 소켓 변수 선언 Socket socket = null; // 2) 소켓 객체 생성 => 서버에 연결요청하기 위해 socket = new Socket(); // 3) 연결하기 , 예외처리 필요 System.out.println("[연결 요청]"); try { // ("localhost",5001) : 서버의 ip, 포트번호 socket.connect(new InetSocketAddress("localhost",5001)); System.out.println("[연결 성공]"); // 4) 서버로 데이터 보낼 코드 작성 byte[] bytes = null; // 바이트 배열선언 String message = null; // 문자열로 변환해 저장할 변수 선언 // 소켓으로부터 아웃풋 스트림을 얻어낸다 OutputStream os = socket.getOutputStream(); // 스트링 변수 message에 문자열 할당 message = "Hello Server"; // message로 부터 바이트 배열 얻기 bytes = message.getBytes("UTF-8"); // 5) output Stream 통해 데이터 전달(to서버) os.write(bytes); os.flush(); System.out.println("[데이터 보내기 성공]"); // 6) 서버로 부터 데이터 받기 InputStream is = socket.getInputStream(); // 길이 100짜리 바이트 배열 생성 bytes = new byte[100]; // input Stream 으로부터 read메소드 호출해 바이트배열 읽기 int readByteCount = is.read(bytes); // 읽은 바이트 배열 문자열로 변환 // bytes 배열 의 0번 인덱스부터 읽은 바이트 수만큼 문자열로 변환 message = new String(bytes,0,readByteCount,"UTF-8"); System.out.println("[데이터 받기 성공] : " + message); os.close(); is.close(); // socket은 아래 예외처리에서 닫아주기때문에 따로 닫는 명령어 작성 X } catch (Exception e) { e.printStackTrace(); } if(!socket.isClosed()) { try { socket.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }
▶ 클라이언트 실행시 출력콘솔