25. 네트워크 소켓(Network Socket) [ JAVA ]

duck-ach·2022년 8월 17일
0

JAVA

목록 보기
25/27
post-custom-banner

네트워크 소켓(Network Socket)

소켓이란 ? 네트워크로 연결되어 있는 컴퓨터의 통신의 접점에 위치한 통신 객체다. 네트워크 통신을 위한 프로그램들은 소켓을 생성하고, 이 소켓을 통해서 서로 데이터를 교환한다.

  • 사전적인 의미로는 연결, 구멍, 콘센트 등을 의미한다.
  • 네트워크 환경에 연결할 수 있게 만들어진 연결부이다.

네트워크 소켓

서버(Server)
1. 수신 소캣을 생성한다. (socket)
2. ip주소와 포트번호를 결정하여 소켓에 적용시킨다. (bind)
3. 클라이언트 요청을 대기하는 상태(listen 상태)로 변경한다. (listen)
4. 서버에 접속한 클라이언트와 통신할 수 있는 새로운 소켓을 생성한다. (accept)
5. 데이터 송수신을 한다. (recv, send)
6. 끝 (close)

클라이언트(Client)
1. 송신 소켓을 생성한다. (socket)
2. 서버에 접속한다. (connect)
3. 데이터를 송수신한다. (recv, send)
4. 끝 (close)

자바로 소켓 프로그래밍 하기

관련 클래스

ServerSocket
: 클라이언트와 통신할 때 사용하는 클래스

InetSocketAddress
: 소켓 사용시 호스트이름(메인주소)과 포트번호를 관리하는 클래스

Socket
: 클라이언트가 서버와 통신할 때 사용하는 클래스

예제 1) 서버 구현하기

		ServerSocket serverSocket = null;
		
		try {
			
			// ServerSocket 생성
			serverSocket = new ServerSocket();
			
			// InetSocketAddress 생성
			InetSocketAddress address = new InetSocketAddress("localhost", 9090);
			
			// ServerSocket에 InetSocketAddress 연결
			serverSocket.bind(address);
			
			// serverSocket는 무한루프로 구현
			while(true) {
				
				System.out.println("[서버] 클라이언트 접속을 기다리는 중");
				Socket client = serverSocket.accept();
				InetSocketAddress clientAddress = (InetSocketAddress)client.getRemoteSocketAddress();
				System.out.println("접속이 허용된 클라이언트 : " + clientAddress.getHostName());
				
				
			}
			
			
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				if(serverSocket.isClosed() == false) {
					serverSocket.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}

ServerSocket()으로 서버를 생성하고, InetSocketAddress()로 주소를 부여한다.
그리고 서버는 클라이언트가 접속된 동안 계속 문제없이 구동되어야 하기때문에 무한루프로 구현을 해보았다.

예제 1) 클라이언트 구현하기

		Socket clientSocket = null;
		
        try {	
			// Socket 생성
			clientSocket = new Socket();
			
			// 접속할 Server의 InetSocketAddress 생성
			InetSocketAddress address = new InetSocketAddress("localhost", 9090);
			
			// 서버에 접속
			clientSocket.connect(address);
			
			System.out.println("[클라이언트] 접속 성공");
			
			
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				if(clientSocket.isClosed() == false) {
					clientSocket.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}

Socket()으로 클라이언트 Socket을 생성하고, InetSocketAddress()를 이용하여 서버와 같은 주소를 부여한다.
그리고 connect()메소드를 활용하여 서버와 연결하면 [클라이언트] 접속 성공메세지를 띄운다.

예제 2) 서버 구현하기

		ServerSocket serverSocket = null;
		
		try {
			// serverSocket 생성
			serverSocket = new ServerSocket();
			
			// serverSocket의 호스트/포트번호 설정
			serverSocket.bind(new InetSocketAddress("localhost", 9099));
			
			// 접속한 클라이언트 개수
			int clientCnt = 0;
			
			// 서버는 종료 없이 무한루프
			while(true) {
				
				System.out.println("[서버] 클라이언트 접속 기다리는 중");
				
				// 클라이언트 접속 및 카운팅
				Socket clientSocket = serverSocket.accept();
				clientCnt++;
				
				// 클라이언트에게 "Welcome" 메시지 전송 (목적지를 명시해야함)
				// 바이트 출력 스트림 중에서 DataOutputStream은 writeUTF() 메소드를 이용해서
				// 한글을 깨짐 없이 보낼 수 있다.
				DataOutputStream out = new DataOutputStream(clientSocket.getOutputStream());
				out.writeUTF("[서버] 게스트 " + clientCnt + "님 환영합니다!");
				
				// 클라이언트가 보낸 메세지 확인
				// 클라이언트가 OutputStream의 write()로 보냈으므로
				// InputStreamReader의 read()로 확인
				InputStreamReader in = new InputStreamReader(clientSocket.getInputStream());
				char[] cbuf = new char[5];
				int readCnt = 0; // 실제로 읽은 바이트 수
				StringBuilder sb = new StringBuilder();
				while((readCnt = in.read(cbuf)) != -1) {
					sb.append(cbuf, 0, readCnt); // byte는 offset지정불가라서 String으로함
				}
				System.out.println("[서버] 클라이언트가 보낸 메세지 : " + sb.toString());
				
				// 입출력 스트림 종료
				in.close();
				out.close();
				
				// 클라이언트 접속 종료
				clientSocket.close();
				
				// 접속한 클라이언트가 3명이면 무한루프 종료
				if(clientCnt == 3) {
					System.out.println("[서버] 서버가 종료되었습니다.");
					serverSocket.close();
					break;
				}
				
			}
		
		} catch (IOException e) {
			e.printStackTrace();
		}

이번엔 클라이언트가 입력한 메세지를 Scanner로 인식하여 서버가 인식하는 프로그램이다.
InputStreamReader를 활용하여 메세지를 읽어오도록 했다.
여기서 중요한 점은 입출력 스트림을 닫아줄 때 가장 나중에 닫아주어야 한다.

profile
자몽 허니 블랙티와 아메리카노 사이 그 어딘가
post-custom-banner

0개의 댓글