정리: 서버소켓은 소켓 간 연결만 처리하고, 실제 데이터 통신은 소켓들 간에 이루어진다.
서버 - 클라이언트 프로그램 간 통신 과정
1. 서버 프로그램은 서버소켓(ServerSocket)을 사용해서 서버 컴퓨터의 특정 포트에서 클라이언트의 연결 요청을 처리할 준비를 한다.
2. 클라이언트 프로그램은 접속할 서버의 IP주소와 포트 정보를 가지고 소켓을 생성해서 서버에 연결을 요청한다.
3. 서버소켓은 클라이언트의 연결 요청을 받으면 서버에 새로운 소켓을 생성해서 클라이언트의 소켓과 연결한다.
4. 클라이언트의 소켓과 새로 생성된 서버의 소켓은 서버소켓과 관계 없이 일대일 통신을 한다.
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.text.SimpleDateFormat;
import java.util.Date;
class TcpIpServer {
public static void main(String[] args) {
ServerSocket serverSocket = null;
try {
// 서버소켓을 생성, 7777 포트와 binding
serverSocket = new ServerSocket(7777);
System.out.println(getTime() + " 서버 준비 완료");
} catch (IOException e) {
e.printStackTrace();
}
while (true) {
try {
System.out.println(getTime() + " 연결 요청 대기");
// 서버소켓은 클라이언트의 연결요청이 올 때까지 실행을 멈추고 기다린다.
// 클라이언트의 연결요청이 오면 클라이언트 소켓과 통신할 새로운 소켓을 생성한다.
Socket socket = serverSocket.accept();
System.out.println(getTime() + socket.getInetAddress());
// 소켓의 출력스트림을 얻는다.
OutputStream out = socket.getOutputStream();
DataOutputStream dos = new DataOutputStream(out);
// 원격 소켓(remote socket)에 데이터를 보낸다.
dos.writeUTF("[Notice] Test Message from Server. First Socket Programming");
System.out.println(getTime() + " 데이터를 전송했습니다.");
// 스트림과 소켓을 닫아준다.
dos.close();
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
static String getTime() {
SimpleDateFormat f = new SimpleDateFormat("[hh시 mm분 ss초]");
return f.format(new Date());
}
}
- Listens for a connection to be made to this socket and accepts it. The method blocks until a connection is made.
- A new Socket s is created and, if there is a security manager, the security manager's checkAccept method is called with s.getInetAddress().getHostAddress() and s.getPort() as its arguments to ensure the operation is allowed. This could result in a SecurityException.
- Returns: the new Socket
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.ConnectException;
import java.net.Socket;
public class TcpIpClient {
public static void main(String[] args) {
try {
String serverIp = "127.0.0.1";
System.out.println("서버에 연결중입니다. 서버IP :" + serverIp);
// 소캣을 생성하여 연결을 요청한다.
Socket socket = new Socket(serverIp, 7777);
// 소켓의 입력스트림을 얻는다.
InputStream in = socket.getInputStream();
DataInputStream dis = new DataInputStream(in);
// 소켓으로부터 받은 데이터를 출력한다.
System.out.println("서버로부터 받은 메시지: " + dis.readUTF());
System.out.println("연결을 종료합니다.");
dis.close();
socket.close();
System.out.println("연결 종료");
} catch (ConnectException ce) {
ce.printStackTrace();
} catch (IOException ie) {
ie.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
}
Source