[JAVA]NETWORK _ Socket

김나영·2022년 8월 16일
0

JAVA

목록 보기
9/14

Socket

  • 클라이언트가 서버와 통신할 때 사용하는 클래스
  • 데이터를 주고 받을 수 있는 구조체로 소켓을 통해 데이터 통로가 만들어진다.

    🔎통신의 단계
    1) 클라이언트가 호스트 이름/IP주소 및 포트 번호로 지정된 서버에 대한 연결 시작
    2) OutputStream을 사용하여 서버에 데이터 전송
    3) InputStream을 사용하여 서버에서 데이터를 읽음
    4) 연결종료

서버방향클라이언트
클라이언트의 요청을 받기 위한 준비를 한다 (ServerSocket)
클라이언트의 요청을 받아 들인다 (accept)서버에 접속 요청을 한다 (Socket)
클라이언트가 보낸 데이터를 출력한다 (BufferedReader)서버에 메시지를 보낸다 (BufferedWriter)
클라이언트에 메시지를 보낸다 (BufferedWriter)서버가 보낸 메시지를 출력한다 (BufferedReader)
종료한다 (Socket.close())종료한다 (Socket.close())

SeverSocket

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

InetSocketAddress

Socket 사용 시 호스트이름과 포트번호를 관리하는 클래스

예제1

→ Server Main

package ex03_socket;

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

public class ServerMain {

	public static void main(String[] args) {
		
		ServerSocket serverSocket = null;
		
		try {
			
			// ServerSocket 생성
			serverSocket = new ServerSocket();
			
			// InetSocketAddress 생성
			InetSocketAddress address = new InetSocketAddress("localhost", 9090);    // http://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();
					System.out.println("서버 중지");
				}
			}catch (IOException e) {
				e.printStackTrace();
			}
		}
		
	}

}


→ Client Main

package ex03_socket;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Socket;

public class ClientMain {

	public static void main(String[] args) {
			
		Socket clientSocket = null;
		
		try {
			
			// Soket생성
			clientSocket = new Socket();
			
			// 접속할 서버
			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();
			}
		}
	}
}


예제2

→ Server Main

package ex04_socket;

import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;

public class ServerMain {

	public static void main(String[] args) {
				
		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 + "님 환영합니다!");
				
				// 클라이언트가 보낸 메시지 확인
				// 클라이언트가 OutputStreamWriter의 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(new String(cbuf, 0 ,readCnt));
				}
				System.out.println("[서버] 클라이언트가 보낸 메시지 : " + sb.toString());
				
				// 입출력 스트림 종료
				out.close();
				in.close();				
				
				// 클라이언트 접속 종료
				clientSocket.close();
								
				// 접속한 클라이언트가 3명이면 무한루프 종료
				if(clientCnt == 3) {
					System.out.println("[서버] 서버가 종료되었습니다.");
					serverSocket.close();	
					break;
				}
				
			}   // while(true)
			
		} catch (IOException e) {
			e.printStackTrace();
		}finally {
			try {
				if(serverSocket.isClosed() == false) {
					System.out.println("[서버] 서버가 종료되었습니다.");
					serverSocket.close();
				}
			}catch(IOException e) {
				e.printStackTrace();
			}
		}
	}
}


→ Client Main

package ex04_socket;

import java.io.DataInputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.util.Scanner;

public class ClientMain {

	public static void main(String[] args) {

		Socket clientSocket = null;
		
		try {
			
			// Socket 생성 및 접속
			clientSocket = new Socket();
			
			// 서버 접속
			clientSocket.connect(new InetSocketAddress("localhost", 9099));
			
			// 서버에 접속되면 Welcome 메시지가 넘어온다, 받아준다
			// 서버가 DataOutputStreamdml writeUTF() 로 메시지를 전송하므로
			// 클라이언트는 DataInputStream의 readUTF()로 메시지를 받음
			DataInputStream in = new DataInputStream(clientSocket.getInputStream());
			String message = in.readUTF();
			System.out.println("[클라이언트]" + message);
		
			// Scanner 클래스를 이용해 입력 받은 데이터를 서버로 보내기
			
			Scanner sc = new Scanner(System.in);
			System.out.println("서버로 전송할 메시지 >>> ");
			String send = sc.nextLine();
			OutputStreamWriter out = new OutputStreamWriter(clientSocket.getOutputStream()) ;
			out.write(send);			
			
			// 입출력 스트림 종료
			out.close();
			in.close();
			sc.close();
			
		} catch(IOException e) {
			e.printStackTrace();
		}finally {
			try {
				if(clientSocket.isClosed() == false) {
					System.out.println("[클라이언트] 클라이언트 종료");
					clientSocket.close();
				}
			}catch(IOException e) {
				e.printStackTrace();		
			}
		}
	}
}
profile
응애 나 애기 개발자

0개의 댓글