1. 소켓 프로그래밍

- 소켓을 이용한 통신 프로그래밍을 뜻한다.

- 소켓(Socket) : 프로세스 간의 통신에 사용되는 양쪽 끝단을 의미한다.

- java.net 패키지를 통해 소켓프로그래밍을 지원한다. TCP와 UDP를 이용한 소켓프로그래밍이 대표적이다.


2. TCP, UDP

- TCP/IP 프로토콜에 포함된 프로토콜, OSI 7계층에 전송계층에 해당한다.

- TCP : 전화에 비유, 데이터를 전송하기 전에 먼저 상대편과 연결을 한 후에 데이터를 전송하고 전송되었는지 확인한다. 실패했다면 재전송한다.

- UDP : 편지에 비유, 연결하지 않고 데이터를 전송하고, 전송되었는지 확인하지 않는다. 데이터를 보낸 순서대로 수신한다는 보장이 없다.

 항목

 TCP 

 UDP 

 연결방식

 연결기반 (connection-oriented), 연결 후 통신, 1:1 통신 방식

 비연결기반(connectionless-oriented) 연결없이 통신(소포), 1:1, 1:n, n:n, 통신방식 

 특징

 데이터의 경계를 구분안함 (byte-stream). 신뢰성 있는 데이터 전송

 데이터의 전송순서가 보장됨, 수신여부를 확인함 (손실되면 재전송)

 패킷을 관리할 필요가 없음, UDP보다 전송속도가 느림

 데이터의 경계를 구분함(datagram), 신뢰성이 없는 데이터 전송

 데이터의 전송순서가 바뀔 수 있음, 수신여부를 확인 안함 (데이터가 손실되어도 알 수 없음)

 패킷을 관리해줘야 함, TCP보다 전송속도가 빠름

 관련 클래스

 Socket, ServerSocket

 DatagramSocket, DatagramPacket, MulticastSocket


3. TCP 소켓 프로그래밍

- 서버와 클라이언트간의 1:1 소켓 통신이다.

- 서버가 먼저 실행되어 클라이언트의 연결요청을 기다리고 있어야 한다.

- Socket : 프로세스간의 통신을 담당, InputStream과 OutputStream을 가지고 있다. 이 두 스트림을 통해 프로세스간의 통신(입출력)이 이루어진다.

- ServerSocket : 포트와 연결(bind)되어 외부의 연결요청을 기다리다 연결요청이 들어오면 Socket을 생성해서 소켓과 소켓간의 통신이 이루어지도록 한다.

한 포트의 하나의 ServerSocket만 연결할 수 있다. (프로토콜이 다르면 같은 포트를 공유할 수 있다.)

1. 서버는 서버소켓을 사용해서 서버 컴퓨터의 특정 포트에서 클라이언트의 연결요청을 처리할 준비를 한다.

2. 클라이언트는 접속할 서버의 IP주소와 포트정보로 소켓을 생성해서 서버에 연결을 요청한다.

3. 서버소켓은 클라이언트의 요청을 받으면 서버에 새로운 소켓을 생성해서 클라이언트의 소켓과 연결되도록 한다.

4. 이제 클라이언트의 소켓과 새로 생성된 서버의 소켓은 서버소켓과 관계없이 1:1통신을 한다.

// TcpServerTest.java

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;

public class TcpServerTest {
	public static void main(String[] args) {
		ServerSocket serverSocket = null;
		
		try {
			// 서버소켓을 생성하고 5000번 포트와 결합(bind) 시킨다.
			serverSocket = new ServerSocket(5000);
			System.out.println(getTime() + " 서버가 준비되었습니다.");
		} catch (IOException e) {
			e.printStackTrace();
		} // try - catch
		
		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("서버로부터의 메세지입니다.");
				System.out.println(getTime() + " 데이터를 전송했습니다.");
				
				// 스트림과 소켓을 달아준다.
				dos.close();
				socket.close();
			} catch (IOException e) {
				e.printStackTrace();
			} // try - catch
		} // while
	} // main
	
	static String getTime() {
		SimpleDateFormat f = new SimpleDateFormat("[hh:mm:ss]");
		return f.format(new Date());
	} // getTime
} // TcpServerTest

/*
 * 
 * 결과
 * [03:33:41] 서버가 준비되었습니다.
 * [03:33:41] 연결요청을 기다립니다.
 * [03:33:43]/127.0.0.1 로부터 연결요청이 들어왔습니다.
 * [03:33:43] 데이터를 전송했습니다.
 * [03:33:43] 연결요청을 기다립니다.
 * 
 */
// TcpClientTest.java

import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.ConnectException;
import java.net.Socket;


public class TcpClientTest {
	public static void main(String[] args) {
		try {
			String serverIP = "127.0.0.1"; // 127.0.0.1 & localhost 본인
			System.out.println("서버에 연결중입니다. 서버 IP : " + serverIP);
			
			// 소켓을 생성하여 연결을 요청한다.
			Socket socket = new Socket(serverIP, 5000);
			
			// 소켓의 입력스트림을 얻는다.
			InputStream in = socket.getInputStream();
			DataInputStream dis = new DataInputStream(in);  // 기본형 단위로 처리하는 보조스트림
			
			// 소켓으로 부터 받은 데이터를 출력한다.
			System.out.println("서버로부터 받은 메세지 : " + dis.readUTF());
			System.out.println("연결을 종료합니다.");
			
			// 스트림과 소켓을 닫는다.
			dis.close();
			socket.close();
		} catch (ConnectException ce) {
			ce.printStackTrace();
		} catch (IOException ie) {
			ie.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		} // try - catch
	} // main
} // TcpClientTest


/*
 *
 * 결과
 * 
 * 서버에 연결중입니다. 서버 IP : 127.0.0.1
 * 서버로부터 받은 메세지 : 서버로부터의 메세지입니다.
 * 연결을 종료합니다.
 * 
 */


+ Recent posts