Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 | 31 |
Tags
- ServerSocket
- Java
- 케밥케이스
- 카멜케이스
- KebabCase
- 파스칼케이스
- UDP통신
- NamingRule
- udp
- camelcase
- DatagramSocket
- DatagramPacket
- 스네이크케이스
- Socket
- tcp
- PascalCase
- SnakeCase
- 명명규칙
Archives
- Today
- Total
MATT's
[JAVA] TCP 통신 (ServerSocket, Socket) 본문
1. 서버 통신 모듈
public class ServerMain {
public static void main(String[] args) {
ServerMain m = new ServerMain();
m.tcpConnect();
}
/*
* TCP 통신 예시 (Server)
*/
private void tcpConnect() {
try (ServerSocket serverSocket = new ServerSocket(8080)) {
System.out.println("ServerSocekt connect...");
// Connection 대기 상태 (.accept())
Socket socket = serverSocket.accept();
System.out.println("Connect success.");
// Server -> Client로 전송할 데이터 write
OutputStream os = socket.getOutputStream();
String sendData = "send data test (server -> client)";
os.write(sendData.getBytes());
// Client -> Server로 전송한 데이터 수신
InputStream is = socket.getInputStream();
byte[] receiveData = new byte[100];
is.read(receiveData);
System.out.println(new String(receiveData));
is.close();
os.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
- 1) Server에서는 ServerSocket을 통해 특정 port(8080)을 열어놓고 TCP 통신을 위한 connection 대기하게 된다.
- 2) Client와 connection이 맺어지게 되면 "Connect success."라는 메세지를 출력하고, Client로 메세지를 전송한다.
- 3) Client에서 메세지를 수신한 후 다시 Server쪽으로 메세지를 전송하여, Server에서는 메세지를 전달받는다.
2. 클라이언트 통신 모듈
public class ClientMain {
public static void main(String[] args) {
ClientMain m = new ClientMain();
m.tcpConnect();
}
/**
* TCP 통신 예시 (Client)
*/
private void tcpConnect() {
try (Socket socket = new Socket()) {
// setSoTimeout : 연결 후 응답에 대한 timeout(3000) 지정
socket.setSoTimeout(3000);
// socket.connect의 인자로 있는 값(4000)은 연결 시의 timeout
socket.connect(new InetSocketAddress("192.168.0.9", 8080), 4000);
System.out.println("Connect Success.");
// Server -> Client로 전송한 데이터 수신
InputStream is = socket.getInputStream();
byte[] receiveData = new byte[100];
is.read(receiveData);
System.out.println(new String(receiveData));
// Client -> Server로 데이터 전송
OutputStream os = socket.getOutputStream();
String clientSendData = "send data test (client -> server)";
os.write(clientSendData.getBytes());
is.close();
os.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
client 쪽의 코드 중 timeout이 2개가 걸려있는 것을 볼 수 있다.
socket.setSoTimeout(3000); 은 서버와의 연결 후 데이터를 요청했을 때, 응답에 대한 timeout을 설정하는 것이고,
socket.connect 메소드의 인자로 있는 값 (여기서는 4000을 뜻한다.)은 connection을 맺는데 걸리는 timeout을 설정하는 것이다.
"중요" 위 코드의 'receiveData' 변수를 보자.
위의 server, client 코드를 보면 'receiveData'는 100크기의 byte 배열로 지정이 되어있다.
server, client 두 쪽다 전달받을 데이터의 크기가 어느정도 될지 알 수 없다.
때문에 위의 코드는 테스트 코드라서 100으로 임의로 지정해둔 것이고, 현직에서는 저렇게 사용하지 않는다.
실제로 사용할 때는 "server에서는 몇 byte 만큼의 데이터를 보낼거니깐 client에서는 몇 byte 만큼의 데이터를 수신하면돼"
라고 약속을 하게 된다. (이것을 정의해놓은 문서를 '프로토콜 문서'라고 한다.)
일반적으로 String 데이터의 경우에는 길이가 짧을 수도 있고 길 수도 있는데, 어떻게 몇 byte만 보내겠다고 지정할 수 있지?
라고 생각할 수 있다.
맞다. 길이가 짧을 수도 있고 길 수도 있는 데이터들에 대해서는 몇 byte로 지정할 수 없다!
때문에 보통 '맨 앞부분 몇 byte는 길이 값을 보내줄게! 그니까 몇 byte만 먼저 받아서 길이 값을 계산하고 뒷부분은 그 길이만큼 받아!' 라고 약속해서 사용한다.
ex.
예를 들어 앞의 4byte는 길이 값을 보낸다고 약속이 되어 있다면,
...
// 보내는 쪽
String sendData = "send data test string";
int dataLength = sendData.length();
os.write(dataLength를 byte[4]로 변환한 값);
os.write(sendData.getBytes());
...
...
// 받는 쪽
byte[] lengthByte = new byte[4];
is.read(lengthByte);
int dataLength = (lengthByte를 int로 변환한 값)
byte[] data = new byte[dataLength];
is.read(data);
...
이런 식으로 사용하여 data를 받아올 수 있는 것이다.
'Java' 카테고리의 다른 글
[Java][테스트툴]JMeter (0) | 2022.05.17 |
---|---|
POI 엑셀 생성 및 다운로드 (feat. RowHandler, ResultHandler) (0) | 2020.06.22 |