프로젝트를 진행중 TCP 통신이 되는지 테스트 해봐야했다
이론적으로는 알고 있었지만 확인하는 법은 몰랐기에
이 기회에 어떻게 구현 할 수 있는지 알아보고
코드도 작성 해보도록 하겠다
1. TCP에 대해서
- tcp 는 연결지향적이라고 할 수 있다
- 연결이 이루어지면 통신 회선이 고정된다
- 데이터는 고정 회선을 통해서만 전달된다
- 보낸 데이터가 순서대로 전달되고 손실이 발생하지 않는다
- 자바에서는 java.net 패키지에서 ServerSocket 과 Socket 클래스를 제공한다
- ServerSocket 은 서버 역할, 서비스를 제공, 요청을 받아서 응답하고 24시간 실행한다
- Socket은 통신할때 사용함하며 객체이다
클라이언트가 연결 요청할때 ServerSocket을 사용해 받고 accept()을 이용해서 수락한다
그 후 Socket(클라이언트) 와 통신하기 위해 Socket을 만든다

TCP 통신을 위해서는 아래와 같은 과정을 거친다
클라이언트 -> 네트워크 어댑터(ip주소) -> 웹서버(포트번호)

연결요청을 위해 클라이언트가 네트워크 어댑터를 가기 위해 ip 주소가 필요하고
서버 프로그램으로 연결한다를 위해 포트번호가 필요하다
2. TCP 서버, 클라이언트 만들어서 데이터 주고 받아보기
아래와 같은 순서로 진행된다
1) 서버를 먼저 돌린다
2) 클라이언트에서 메세지를 보낸다
3) 보낸 메세지를 서버에서 받는다
4) 받은 메세지를 다시 클라이언트에게 보낸다
5) 클라이언트가 메세지를 받는다
6) 클라이언트 종료한다
7) 서버는 계속 돌고 있는다
아래 샘플 코드를 작성해 두겠다
주석을 달아 뒀기에 참고하면 될것 같다
서버
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;
public class EchoServerExample {
private static ServerSocket serverSocket;
public static void main(String[] args) {
System.out.println("-----------------------------");
System.out.println("서버를 종료하려면 q 또는 Q를 입력하고 Enter를 입력하세요.");
System.out.println("-----------------------------");
// TCP 서버 시작
startServer();
// 키보드 입력
Scanner scanner = new Scanner(System.in);
while (true) {
String key = scanner.nextLine();
if (key.toLowerCase().equals("q")) {
break;
}
}
scanner.close();
// TCP 서버 종료
stopServer();
}
public static void startServer() {
// 작업 스레드 정의
Thread thread = new Thread() {
@Override
public void run() {
// ServerSocket 생성 및 Port 바인딩
try {
serverSocket = new ServerSocket(50001);
System.out.println("[서버] 시작됨");
while (true) {
System.out.println("\n[서버] 연결 요청을 기다림\n");
// 연결 수락
Socket socket = serverSocket.accept();
// 연결된 클라이언트 정보
InetSocketAddress isa = (InetSocketAddress) socket.getRemoteSocketAddress();
String clientIp = isa.getHostString();
System.out.println("[서버] " + clientIp + "의 연결 요청을 수락함");
// 데이터 받기
InputStream is = socket.getInputStream();
byte[] bytes = new byte[1024];
int readByteCount = is.read(bytes);
String message = new String(bytes, 0, readByteCount, "UTF-8");
System.out.println("[서버] 데이터 받음: " + message);
/*
// 데이터 받기 간편하게 만들기
DataInputStream dis = new DataInputStream(socket.getInputStream());
String message = dis.readUTF();
*/
// 데이터 보내기
OutputStream os = socket.getOutputStream();
bytes = message.getBytes("UTF-8");
os.write(bytes);
os.flush();
System.out.println("[서버] 받은 데이터를 다시 보냄: " + message);
/*
// 데이터 보내기 간편하게 만들기
DataOutputStream dos = new DataOutputStream(socket.getOutputStream());
dos.writeUTF(message);
dos.flush();
*/
// 연결 끊기
socket.close();
System.out.println("[서버] " + clientIp + "의 연결을 끊음");
}
} catch (IOException e) {
System.out.println("[서버] " + e.getMessage());
}
}
};
// 스레드 시작
thread.start();
}
public static void stopServer() {
// ServerSocket을 닫고 Port 인바인디
try {
serverSocket.close();
} catch (IOException e) {
}
}
}
클라이언트
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
public class EchoClientExample {
public static void main(String[] args) {
try {
Socket socket = new Socket("localhost", 50001);
System.out.println("[클라이언트] 연결 성공");
// 데이터 보내기
String sendMessage = "나는 자바가 좋아!";
OutputStream os = socket.getOutputStream();
byte[] bytes = sendMessage.getBytes("UTF-8");
os.write(bytes);
os.flush();
System.out.println("[클라이언트] 데이터 보냄: " + sendMessage);
/*
// 데이터 보내기 간편하게 만들기
DataOutputStream dos = new DataOutputStream(socket.getOutputStream());
dos.writeUTF(sendMessage);
dos.flush();
*/
// 데이터 받기
InputStream is = socket.getInputStream();
bytes = new byte[1024];
int readByteCount = is.read(bytes);
String receiveMessage = new String(bytes, 0, readByteCount, "UTF-8");
System.out.println("[클라이언트] 보낸 데이터를 다시 받음: " + receiveMessage);
/*
// 데이터 받기 간편하게 만들기
DataInputStream dis = new DataInputStream(socket.getInputStream());
String receiveMessage = dis.readUTF();
*/
socket.close();
System.out.println("[클라이언트] 연결 끊음");
} catch (UnknownHostException e) {
// IP 또는 도메인 표기 방법이 잘못되었을 경우
System.out.println("UnknownHostException: " + e.toString());
} catch (IOException e) {
// IP 또는 Port 번호가 존재하지 않을 경우
System.out.println("IOException: " + e.toString());
}
}
}
'Java' 카테고리의 다른 글
[Java] 인수(Argument), 인자(Parameter) (0) | 2023.08.28 |
---|---|
[Java] UDP 통신 코드로 이해 해보기 (0) | 2023.08.14 |
[Java] String, StringBuffer, StringBuilder 차이 및 장단점 (2) | 2023.08.04 |
[Java] 로그 사용법 (Log4j2) (0) | 2023.07.21 |
[Java] 로그 개념정리 (SLF4J, Log4j, Logback, Log4j2) (0) | 2023.07.21 |