9. TCP 소켓 프로그래밍1

TCP

TCP : 스트림(stream) 통신 프로토콜
양쪽의 소켓이 연결된 상태에서 통신이 가능하다. (연결지향 프로토콜)
신뢰성 있는 데이터 통신
한 번 연결이 되면 연결이 끊어 질 때까지 송신한 데이터는 차례대로 목적지의 소켓에 전달
자바는 java.net 패키지에 TCP 소켓 프로그래밍을 쉽게 하도록 관련 클래스를 제공하고 있다.
라이브러리의 사용법과 동작순서를 정확하게 이해하고 있어야 한다.
ServerSocket과 Socket 클래스를 사용하게 된다.

TCPServer.java
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
public class TCPSever {
private static final int SERVER_PORT = 5000;

public static void main(String[] args) {

ServerSocket serverSocket = null;
try {
// 1. 서버 소켓 생성
serverSocket = new ServerSocket();

// 2. 바인딩( Binding )
InetAddress inetAddress = InetAddress.getLocalHost();
String localhostAddress = inetAddress.getHostAddress();

serverSocket.bind(new InetSocketAddress(localhostAddress, SERVER_PORT));
System.out.println("[Server] binding " + localhostAddress);

// 3. 연결 요청 기다림( accept)
Socket socket = serverSocket.accept(); // blocking

// 4. 연결성공
InetSocketAddress remoteSocketAddress = (InetSocketAddress) socket.getRemoteSocketAddress();

int remoteHostPort = remoteSocketAddress.getPort();
String remoteHostAddress = remoteSocketAddress.getAddress().getHostAddress();
System.out.println("[server] connected from " + remoteHostAddress + remoteHostPort);
try {
// 5. I/O Stream 받아오기
InputStream is = socket.getInputStream();
OutputStream os = socket.getOutputStream();

while (true) {
// 6. 데이터 읽기
byte[] buffer = new byte[256];
int readByteCount = is.read(buffer); // block

if (readByteCount <= -1) { //정상종료
System.out.println("[server] disconnection by client");
break;
}

String data = new String(buffer, 0, readByteCount, "utf-8");
System.out.println("[server] received : " + data);

// 7. 데이터 쓰기
os.write(data.getBytes("utf-8"));
}

} catch(SocketException e) {
// 상대편이 소켓을 정상적으로 닫지 않고 종료한 경우
System.out.println("[server] sudden closed by client");

}catch (IOException e) { // 소켓과 관련된 캐치
e.printStackTrace();
} finally {
try {
if (socket != null && socket.isClosed() == false) {
socket.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}

} catch (IOException e) { // 서버소켓과 관련된 캐치
e.printStackTrace();
} finally {
try {
if (serverSocket != null && serverSocket.isClosed() == false) {
serverSocket.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}

TCPClient.java
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
public class TCPClient {
private static final String SERVER_IP = "192.168.111.1";
private static final int SERVER_PORT = 5000;

public static void main(String[] args) {
Socket socket = null;
try {

// 1. Socket 생성
socket = new Socket();

// 2. 서버 연결
socket.connect(new InetSocketAddress(SERVER_IP, SERVER_PORT));

// 3. I/O 받아오기
InputStream is = socket.getInputStream();
OutputStream os = socket.getOutputStream();

// 4. 쓰기 / 읽기
String data = "hello";
os.write( data.getBytes( "utf-8" ));

byte[] buffer = new byte[256];
int readByteCount = is.read( buffer );
if( readByteCount <= -1) {
System.out.println( "[client] disconnection by server");
return;
}

data = new String( buffer, 0, readByteCount, "utf-8");
System.out.println("[client] received:"+ data);
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (socket != null && socket.isClosed() == false) {
socket.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}

에코서버, 클라이언트 만들기

EchoServer.java
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
public class EchoServer {
private static final int SERVER_PORT = 5000;
public static void main(String[] args) {
ServerSocket serverSocket = null;
try {
// 1. 서버 소켓 생성
serverSocket = new ServerSocket();

// 2. 바인딩( Binding )
InetAddress inetAddress = InetAddress.getLocalHost();
String localhostAddress = inetAddress.getHostAddress();

serverSocket.bind(new InetSocketAddress(localhostAddress, SERVER_PORT));
System.out.println("[Server] binding " + localhostAddress);

// 3. 연결 요청 기다림( accept)
Socket socket = serverSocket.accept(); // blocking

// 4. 연결성공
InetSocketAddress remoteSocketAddress = (InetSocketAddress) socket.getRemoteSocketAddress();

int remoteHostPort = remoteSocketAddress.getPort();
String remoteHostAddress = remoteSocketAddress.getAddress().getHostAddress();
System.out.println("[server] connected from " + remoteHostAddress + remoteHostPort);
try {
// 5. I/O Stream 받아오기
InputStream is = socket.getInputStream();


BufferedReader br = new BufferedReader( new InputStreamReader( is, "UTF-8" ));

PrintWriter pw = new PrintWriter(socket.getOutputStream(), true);
// auto flush를 true로 한다. true로 안하면
//버퍼가 다찬다음 나가기 때문에 늦게나간다.
while (true) {
// 6. 데이터 읽기
String message = br.readLine();

if ( message == null ) { //정상종료
System.out.println("[server] disconnection by client");
break;
}

System.out.println("[server] received : " + message);

// 7. 데이터 쓰기
pw.println(message);
}

} catch(SocketException e) {
// 상대편이 소켓을 정상적으로 닫지 않고 종료한 경우
System.out.println("[server] sudden closed by client");

}catch (IOException e) { // 소켓과 관련된 캐치
e.printStackTrace();
} finally {
try {
if (socket != null && socket.isClosed() == false) {
socket.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}

} catch (IOException e) { // 서버소켓과 관련된 캐치
e.printStackTrace();
} finally {
try {
if (serverSocket != null && serverSocket.isClosed() == false) {
serverSocket.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
EchoClient.java
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
public class EchoClient {
private static final String SERVER_IP = "192.168.111.1";
private static final int SERVER_PORT = 5000;
static Scanner scanner;
public static void main(String[] args) {
Socket socket = null;
try {

// 1. Socket 생성
socket = new Socket();

// 2. 서버 연결
socket.connect(new InetSocketAddress(SERVER_IP, SERVER_PORT));

// 3. I/O 받아오기
BufferedReader br =
new BufferedReader( new InputStreamReader(socket.getInputStream()));
PrintWriter pw = new PrintWriter( new OutputStreamWriter(socket.getOutputStream(),"UTF-8"),true);

// 4. 쓰기 / 읽기
scanner = new Scanner(System.in);
while(true) {
System.out.print( ">>" );
String message = scanner.nextLine();

if("exit".equals(message)) {
break;
}

//메세지 보내기
pw.println( message );

//에코 메시지 받기
String echoMessage = br.readLine();
if( echoMessage == null) {
System.out.println("[client] Disconnection by Server");
}

//출력
System.out.println( "<<" + echoMessage );

}


} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (socket != null && socket.isClosed() == false) {
socket.close();
}
} catch (IOException e) {
e.printStackTrace();
}
scanner.close();
}
}
}
Share