11.소켓과 스레드의 결합

여러 클라이언트가 접속가능한 서버

EchoServerReceiveThread.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
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);

while(true) {
// 3. 연결 요청 기다림( accept)
Socket socket = serverSocket.accept(); // 반복문 내에서 blocking이 되기떄문에 CPU를 많이먹지 않는다.
new EchoServerReceiveThread( socket ).start();
}

}
catch (IOException e) { // 서버소켓과 관련된 캐치
e.printStackTrace();
} finally {
try {
if (serverSocket != null && serverSocket.isClosed() == false) {
serverSocket.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
private static void consoLog( String log ) {
System.out.println( "[server:" );

}
}
EchoServerReceiveThread.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

public class EchoServerReceiveThread extends Thread {
private Socket socket;
public EchoServerReceiveThread( Socket socket ) {
this.socket = socket;
}
@Override
public void run() {
// 4. 연결성공
InetSocketAddress remoteSocketAddress = (InetSocketAddress) socket.getRemoteSocketAddress();

int remoteHostPort = remoteSocketAddress.getPort();
String remoteHostAddress = remoteSocketAddress.getAddress().getHostAddress();
consoleLog("connected from "+ remoteHostAddress);
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) { // 정상종료
consoleLog("disconnection by client");
break;
}

consoleLog(" received : " + message);

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

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

} catch (IOException e) { // 소켓과 관련된 캐치
e.printStackTrace();
} finally {
try {
if (socket != null && socket.isClosed() == false) {
socket.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
private void consoleLog(String log) {
System.out.println("[Server: "+getId() + "]" + log);

}

}

Share