Java 기반 TCP/IP 네트워크 프로그래밍
TCP
Transmission Control Protocol
전송 제어 프로토콜 -> 데이터 전달 보증
IP
Internet Protocol
각자 컴퓨터가 인터넷에 연결된 IP가 있습니다.
PORT
포트, 서비스 번호(입구), 가상의 연결단위
80포트는 생략가능합니다.
Socket
네트워크의 양끝 단위로서 통신을 위한 인터페이스를 의미합니다.
소켓은 뭐랄까... 포수에게 공을 던져지는 공 같다고 해야할까요... 뒤에서 더 자세하게 설명해보겠습니다.
ServerSocket
서버에서 생성하는 서버 소켓
서버소켓은 포수라고 할 수 있겠습니다. 소켓을 받는 서버소켓입니다.
예시를 보면서 이해해볼까요?
예시
서버와 클라이언트 두개로 나눠서 예시를 들어보겠습니다.
package step2.server;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;
/*
* NetServer2
* 서버는 클라이언트 접속을 대기하다가
* 클라이언트 접속하면 ( accept() 실행) 담당 소켓을 리턴받아
* 클라이언트가 보낸 메세지를 입력받아 화면에 출력
* socket.getInputStream() < InputStreamReader < BufferedReader
*/
public class NetServer2 {
public void go() throws IOException {
ServerSocket serverSocket=null;
try {
serverSocket=new ServerSocket(5432);
System.out.println("**NetServer2 실행**");
while(true) {
//접속을 대기하다가 클라이언트가 접속하면 동작하여 클라이언트 담당 개별 소켓을 반환
Socket socket=serverSocket.accept();
System.out.println("**"+socket.getInetAddress()+"님 접속하셨습니다**");
//클라이언트가 보낸 메세지를 입력
// InputStreamReader : 바이트 스트림을 문자열 스트림으로 변환
BufferedReader br=new BufferedReader(new InputStreamReader(socket.getInputStream(),"utf-8"));
System.out.println(socket.getInetAddress()+"님의 메세지:"+br.readLine());
socket.close();
}
}finally {
if(serverSocket!=null)
serverSocket.close();
}
}
public static void main(String[] args) {
try {
new NetServer2().go();
} catch (IOException e) {
e.printStackTrace();
}
}
}
먼저 서버쪽 코드를 확인해보겠습니다.
serverSocket=new ServerSocket(5432);
서버소켓 객체를 생성해주었는데 포트번호 5432로 생성해주었습니다. 이것을 그냥 5432번 방의 문을 개방해서 고객들이 들어오게 했다고 하겠습니다.
while(true) {
Socket socket=serverSocket.accept();
System.out.println("**"+socket.getInetAddress()+"님 접속하셨습니다**");
BufferedReader br=new BufferedReader(new InputStreamReader(socket.getInputStream(),"utf-8"));
System.out.println(socket.getInetAddress()+"님의 메세지:"+br.readLine());
socket.close();
}
1. 소켓이 들어오면 서버소켓이 승락을해서 소켓을 return 하고 socket을 할당해줍니다.
2. getInetAddress() 메소드를 이용해서 상대방의 IP를 확인할 수 있습니다.
3. socket.getInputStream() 을 이용해서 소켓의 입력 스트림을 받아옵니다. (1byte)
4. 한글은 1byte로 표현되지 않아서 InputStramReader를 이용하여 utf-8로 인코딩 진행
5. 이후 BufferedReader로 텍스트를 읽고 문자, 배열 및 선을 효율적으로 읽을 수 있도록 문자를 버퍼링합니다.
이렇게 해서 소켓으로 넘어오는 데이터를 읽을 수 있습니다.
다음으로 client에서는 어떤 코드가 있는지 알아보겠습니다.
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;
import common.IP;
/*
* Socket 을 생성 -> 서버에 접속하여
* 자신의 메세지를 서버로 출력한 후 종료
*/
public class NetClient2 {
public void go() throws UnknownHostException, IOException {
Socket socket=null;
try {
socket=new Socket(IP.INST_IP,5432);
PrintWriter pw=new PrintWriter(new OutputStreamWriter(socket.getOutputStream(),"utf-8"),true);//true:autoflush
pw.println("호소세 블로그 화이팅!");
System.out.println("서버에 접속해 메세지를 출력");
}finally {
if(socket!=null)
socket.close();
}
}
public static void main(String[] args) {
try {
new NetClient2().go();
} catch (IOException e) {
e.printStackTrace();
}
}
}
1. Socket 객체 생성을 위해 IP주소(서버)와 포트번호를 작성하고 생성자를 통해 소켓 객체 생성
2. getOutputStream() 메소드를 통해 소켓 객체 출력 스트림을 반환합니다.
3. OutputStreamWriter 생성자를 통해 1byte 코드를 utf-8로 인코딩합니다.
4. PrintWriter로 텍스트 출력 스트림으로 만들어 줍니다.
5. 문자열을 객체에 프린트해서 저장합니다.
이렇게 만든 객체를 IP:Port에 보내면 서버소켓이 클라이언트의 소켓을 받아서 읽어주는 것입니다.
위에 작성한 예시는 서버소켓 집에 소켓 고객이 오면 소켓 고객이 하고 싶은 이야기를 말해주는 서비스입니다. "호소세 블로그 화이팅!"이라는 문구를 말이지요.
소감
이렇게 서버 통신을 해보았는데요. 아직 뭔가 아쉬운 것이 있다면? 서버에서 클라이언트의 내용을 읽어주기만 하고 각각의 IP에는 보내주지 않고 있다는 점입니다. 아마도 클라이언트 서버에서도 이제 반복문을 사용할 것 같고, 서버에서는 자신과 연결된 IP들과의 연결을 끊지 않고 계속 이어주면서 받은 값들을 여러 소켓에 보내줄 내용이 남은 것 같습니다.
다음 시간에는 소켓의 지속 연결에 대하여 알아볼 것 같습니다.
'코딩 개발 > Java' 카테고리의 다른 글
Java - DB연결을 위한 Cloud Service (feat. AWS EC2, ORACLE) (4) | 2023.04.30 |
---|---|
Java - Network 응용 심화편(장코드 주의) (0) | 2023.04.26 |
Java - Thread, Runnable (4) | 2023.04.23 |
Java - ObjectInputStream & ObjectOutputStream (2) | 2023.04.20 |
Java - File Class에 대한 간단한 예제 (0) | 2023.04.18 |