네트워크 상에서 수행되는 두 프로그램 간 양방향 통신링크의 한쪽 끝 단을 의미
소켓은 특정 포트 번호와 연결되어 있음
-> TCP에서 데이터를 보낼 응용 프로그램을 식별할 수 있음 ex) 웹서버는 80포트 이용
자바에서의 데이터 통신 시 소켓 사용
소켓 종류
-> 서버 소켓과 클라이언트 소켓
클라이언트 소켓 생성 및 서버에 접속
-> Socket 객체 생성되면 곧 바로 128.12.1.1의 주소로 자동 접속
네트워크 입출력 스트림 생성
읽기위해 : BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getIntputStream()));
쓰기위해 : BufferedWriter out = new BufferedWriter(new OutputStreamWriter(clientSocket.getOutputStream()));
-> 일반 스트림을 입출력하는 방식과 동일
서버로 데이터 전송
-> flush()를 호출하면 스트림 속에 데이터를 남기지않고 모두 전송
out.write("hello" + "\n");
out.flush();
int x = in.read(); //서버로부터 한 개의 문자 수신
String line = in.readline(); //서버로부터 한 행의 문자열 수신
clientSocket.close();
서버 소켓에 사용되는 클래스
java.net 패키지에 포함
주요 생성자
주요 메소드
-> accept() : 새 소켓 객체를 만들어서, 클라이언트와 연결되게 하는것
서버는 서버 소켓으로 들어오는 연결 요청을 기다림
클라이언트가 서버에게 연결 요청 (특정 포트번호로 접속)
서버가 연결 요청을 수락하고, 새로운 소켓을 만들어 클라이언트와 연결 생성
(빨간 박스 = 새로운 소켓)
서버 소켓 생성
-> 이미 사용중인 포트 번호를 지정하면 오류가 발생
ServerSocket serverSocket = new ServerSocket(5550);
클라이언트로부터 접속 기다림
Socket socket = servetSocket.accept();
-> accept()메소드는 연결 요청이 오면 새로운 Socket 객체 반환
-> 서버에서 클라이언트와의 데이터 통신은 새로 만들어진 Socket 객체를 통해서 이루어짐
-> ServerSocket 클래스는 Socket 클래스와 달리 주어진 연결에 대해 입출력 스트림을 만들어주는 메소드가 없음
네트워크 입출력 스트림 생성
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(socket.OutputStream()));
-> accept() 메소드에서 얻은 Socket객체의 getInputStream()과 getOutputStream()메소드를 이용하여 데이터 스트림 생성
-> 일반 스트림을 입출력하는 방식과 동일하게 네트워크 데이터 입출력
int x = in.read(); //클라이언트로부터 한 개의 문자 수신
String line = in.readline(); //클라이언트로부터 한 행의 문자열 수신
out.write("Hi!, Client" + "\n");
out.flush();
-> flush()를 호출하면 스트림 속에 데이터를 남기지 말고 모두 전송
네트워크 접속 종료
socket.close();
-> 만들었던 소켓을 없애야하고
서버 응용프로그램 종료
serverSocket.close();
-> 더 이상 클라이언트의 접속을 받지 않고 서버 응용 프로그램을 종료하고자 하는 경우 ServerSocket 종료
-> 서버 종료
서버 소켓 생성
ServerSocket listener = new ServerSocket(9999);
-> 시스템에서 사용되지 않은 포트 번호로 서버 소켓 생성
클라이언트 요청 대기
Socket socket = listener.accept();
-> 클라이언트가 연결 요청이 올 때까지 소켓 기다림
-> 해당 포트 번호로 연결 요청이 오면 수락과 함께 새로운 소켓을 생성 / 새 소켓으로 클라이언트와 통신
-> 새로운 소켓의 포트 번호는 자동으로 할당
클라이언트와 통신을 위한 입출력 스트림 생성
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(socket.OutputStream()));
-> 스트림을 생성하여 클라이언트와 데이터 송수신
데이터 종류에 따라 바이트 스트림 또는 문자 스트림을 생성
채팅과 같이 문자열을 송수신하는 경우는 문자 스트림 사용
효율적 입출력을 위하여 버퍼 스트림(Buffered Stream) 사용
클라이언트의 데이터 수신
String inputMessage = in.readLine();
-> 스트림 생성 이후는 데이터 입력 받는 방법과 동일
-> 클라이언트에서 한 행의 문자열을 보내올 때까지 기다림
클라이언트에 데이터 송신
String outputMessage = stin.readLine();
out.write("서버>" + outputMessage + "\n");
out.flush();
-> 스트림 생성 이후는 일반 데이터를 출력하는 방법과 동일
-> 콘솔에서 입력 받은 문자열을 클라이언트로 송신
-> flush() 메소드로 스트림의 모든 데이터를 클라이언트로 송신
socket.close();
listener.close();
-> 데이터의 송수신이 끝나면 소켓을 닫아야함
-> 소켓을 닫으면 소켓의 입출력 스트림도 같이 닫힘
-> 서버 소켓을 닫으면 클라이언트 연결 요청을 받을 수 없음
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;
public class ServerEx {
public static void main(String[] args) {
ServerSocket server = null;
Socket socket = null;
BufferedReader in = null;
BufferedWriter out = null;
Scanner sc = new Scanner(System.in);
try {
server = new ServerSocket(9999); //이미 사용중인 포트면 에러발생
System.out.println("연결 대기중.....");
socket = server.accept();
System.out.println("연결 되었습니다.");
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
out = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
while(true) {
String inMsg = in.readLine();
if(inMsg.equalsIgnoreCase("bye")) {
System.out.println("클라이언트가 나갔습니다.");
break;
}
//정상 메시지인 경우
System.out.println("클라이언트 : " + inMsg);
System.out.print("보내기 >>");
String outMsg = sc.nextLine();
out.write(outMsg + "\n");
out.flush();
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try{
sc.close();
out.close();
in.close();
socket.close();
server.close();
}catch (IOException e) {
e.printStackTrace();
}
}
}
}
지금은 콘솔에서 입력받기때문에 커서가 입력받을 때까지 계속 대기상태로 기다리고있지만, GUI로 동작하게하면 기다리지않고, 들어오면 동작하게 처리가능
출처
https://www.youtube.com/watch?v=dX82Wuc18wk
https://kadosholy.tistory.com/125