Java Socket 프로그래밍 상세 정보 및 예제 코드

소켓은 플러그인이라고도 부른다. 소켓은 컴퓨터 네트워크 통신의 기본적인 기술 중의 하나다.현재 대부분의 인터넷 기반 소프트웨어, 예를 들어 브라우저, 실시간 통신 도구, 심지어 P2P 다운로드는 모두 Socket을 바탕으로 이루어진다.본고는 TCP/IP 기반의 Socket 프로그래밍과 클라이언트/서버 프로그램을 어떻게 쓰는지 소개한다.
디저트
유닉스의 입출력(IO) 시스템은 Open-Read-Write-Close와 같은 조작 범본을 따른다.사용자 프로세스가 IO 작업을 수행하기 전에 Open을 호출하여 작업 중인 파일이나 장치의 읽기 또는 쓰기 권한을 지정하고 가져와야 합니다.IO 작업 대상이 열리면 이 사용자 프로세스는 이 대상을 한 번 또는 여러 번 읽거나 쓸 수 있습니다.Read 작업은 IO 작업 대상에서 데이터를 읽고 사용자 프로세스에 전달하는 데 사용됩니다.Write 작업은 사용자 프로세스의 데이터를 입출력 작업 객체에 전달(쓰기)하는 데 사용됩니다.모든 Read와 Write 작업이 끝나면 사용자 프로세스는 Close를 호출하여 IO 대상에 대한 사용을 완료하도록 알려야 합니다.
유닉스가 프로세스 간 통신(InterProcess Communication, 약칭 IPC)을 지원하기 시작할 때 IPC의 인터페이스는 파일 IO 조작 인터페이스와 유사하게 설계되었다.유닉스에서 프로세스에는 읽기 및 쓰기를 위한 입출력 설명자 세트가 있습니다.입출력 설명자는 파일, 장치 또는 통신 채널 (socket 소켓) 일 수 있습니다.파일 설명자는 세 부분으로 구성되어 있습니다. 만들기(socket 열기), 쓰기 데이터 읽기(socket에 받아들이고 보내기), 삭제(socket 닫기)입니다.
유닉스 시스템에서 클래스 BSD 버전의 IPC 인터페이스는 TCP와 UDP 프로토콜 위의 한 층으로 이루어진다.메시지의 목적지는 socket 주소로 표시합니다.socket 주소는 네트워크 주소와 포트 번호로 구성된 통신 식별자입니다.
프로세스 간 통신 작업에는 socket 한 쌍이 필요합니다.프로세스 간 통신은 한 프로세스의 socket과 다른 프로세스의 다른 socket을 통해 데이터 전송을 합니다.메시지가 실행된 후, 이 메시지는 송신단의 socket에서 줄을 서 있으며, 하층의 네트워크 프로토콜이 이 메시지를 보낼 때까지.메시지가 수신자의 socket에 도착하면 수신자의 프로세스가 이 메시지를 수신 처리할 때까지 줄을 서 있습니다.
TCP 및 UDP 통신
socket 프로그래밍에 관해서 우리는 두 가지 통신 프로토콜을 선택할 수 있다.하나는 데이터 보고 통신이고, 다른 하나는 흐르는 통신이다.
데이터 보고 통신
데이터 보고 통신 프로토콜은 우리가 흔히 말하는 UDP(User Data Protocol 사용자 데이터 보고 프로토콜)입니다.UDP는 연결이 없는 프로토콜입니다. 이것은 우리가 데이터 메시지를 보낼 때마다 본 컴퓨터의 socket 설명자와 수신단의 socket 설명자를 동시에 보내야 한다는 것을 의미합니다.따라서 우리는 통신할 때마다 추가 데이터를 보내야 한다.
흐름 통신
흐름 통신 프로토콜은 TCP(Transfer Control Protocol, 전송 제어 프로토콜)라고도 부른다.UDP와 달리 TCP는 연결 기반 프로토콜입니다.흐름 통신을 사용하기 전에, 우리는 반드시 통신의 한 쌍의 socket 사이에 연결을 구축해야 한다.그 중 하나는 서버로 감청 연결 요청을 한다.다른 하나는 클라이언트로 연결 요청을 하는 것이다.일단 두 개의 socket이 연결되면 그들은 단방향 또는 양방향으로 데이터 전송을 할 수 있다.
여기까지 읽으면 우리가 socket 프로그래밍을 하는데 UDP를 사용할까요, TCP를 사용할까요.어떤 프로토콜을 기반으로 하는 socket 프로그래밍을 선택하는지는 구체적인 클라이언트-서버 프로그램의 응용 장면에 달려 있습니다.TCP와 UDP 프로토콜의 차이점을 간단히 분석하면 어떤 것을 더 잘 사용할 수 있는지 선택할 수 있습니다.
UDP에서 데이터 메시지를 보낼 때마다 이 컴퓨터의 socket 설명자와 수신단의 socket 설명자를 첨부해야 합니다.한편, TCP는 연결 기반 프로토콜이기 때문에 통신의 socket 쌍 간에 통신하기 전에 연결을 구축해야 하기 때문에 연결을 구축하는 데 소모되는 시간이 TCP 프로토콜에 존재하는 socket 프로그래밍이 있다.
UDP에서 데이터 보고 데이터는 크기에 64KB의 제한이 있습니다.TCP에도 이러한 제한이 없습니다.일단 TCP 통신의 socket이 연결되면 그들 사이의 통신은 IO 흐름과 유사하고 모든 데이터는 받아들일 때의 순서에 따라 읽힌다.
UDP는 신뢰할 수 없는 프로토콜로 전송된 데이터 보고가 반드시 송신 순서에 따라 수신단의 socket에 의해 받아들여지는 것은 아니다.그리고 TCP는 신뢰할 수 있는 프로토콜입니다.수신단이 받은 가방의 순서와 가방이 발송단에서 받은 순서는 일치합니다.
요컨대 TCP는 원격 로그인(rlogin,telnet)과 파일 전송(FTP) 같은 네트워크 서비스에 적합하다.전송해야 할 데이터의 크기가 확실하지 않기 때문이다.UDP는 TCP보다 훨씬 간단하고 가볍습니다.UDP는 실시간성이 높거나 패킷을 잃어버리는 데 중요하지 않은 일부 서비스에 사용됩니다.LAN에서 UDP의 패킷 손실률이 상대적으로 낮습니다.
Java의 socket 프로그래밍
다음 부분에서 나는 몇 가지 예시를 통해 socket을 사용하여 클라이언트와 서버 측의 프로그램을 작성하는 방법을 설명할 것이다.
주의: 다음 예시에서 저는 TCP/IP 프로토콜을 기반으로 하는 socket 프로그래밍을 사용할 것입니다. 왜냐하면 이 프로토콜은 UDP/IP보다 훨씬 광범위하게 사용되기 때문입니다.그리고 모든 socket 관련 클래스는java에 있습니다.net 패키지 아래, 그래서 우리가 socket 프로그래밍을 할 때 이 패키지를 도입해야 합니다.
클라이언트 작성
소켓 열기
클라이언트에 있으면, 다음 코드를 쓰면 socket을 열 수 있습니다.

String host = "127.0.0.1";
int port = 8919;
Socket client = new Socket(host, port);
위 코드에서host는 클라이언트가 연결해야 하는 기계이고port는 서버 측에서 요청을 감청하는 포트입니다.포트를 선택할 때 주의해야 할 점은 0~1023 포트가 이미 시스템에 예약되어 있다는 것이다.이 포트들은 메일, FTP, HTTP 등 자주 사용하는 서비스에 사용된다.서버 측의 코드를 작성하고 포트를 선택할 때 1023보다 큰 포트를 선택하십시오.
데이터 쓰기
다음은 요청 데이터를 쓰는 것입니다. 클라이언트의 socket 대상에서 OutputStream 대상을 얻고 데이터를 쓴 후입니다.파일 IO와 유사한 처리 코드입니다.

public class ClientSocket {
 public static void main(String args[]) {
    String host = "127.0.0.1";
    int port = 8919;
    try {
     Socket client = new Socket(host, port);
     Writer writer = new OutputStreamWriter(client.getOutputStream());
     writer.write("Hello From Client");
     writer.flush();
     writer.close();
     client.close();
    } catch (IOException e) {
     e.printStackTrace();
    }
  }
 
}
입출력 객체 닫기
파일 IO와 유사하게 읽기와 쓰기가 끝난 후에 IO 대상을 닫아서 자원의 정확한 방출을 확보해야 합니다.
서버 측 작성
서버 쪽 socket 열기

int port = 8919;
ServerSocket server = new ServerSocket(port);
Socket socket = server.accept();
위의 코드는 서버 측의 socket을 만들고 accept 방법을 호출하여 클라이언트의 요청 socket을 감청하고 가져옵니다.accept 방법은 차단 방법으로 서버 측과 클라이언트 간의 연결을 맺기 전에 차단을 기다립니다.
데이터 읽기
위에서 얻은 socket 대상을 통해 InputStream 대상을 얻고 파일 IO를 설치하여 데이터를 읽으면 됩니다.여기서 우리는 내용을 인쇄할 것이다.

public class ServerClient {
 public static void main(String[] args) {
    int port = 8919;
    try {
      ServerSocket server = new ServerSocket(port);
        Socket socket = server.accept();
      Reader reader = new InputStreamReader(socket.getInputStream());
      char chars[] = new char[1024];
      int len;
      StringBuilder builder = new StringBuilder();
      while ((len=reader.read(chars)) != -1) {
        builder.append(new String(chars, 0, len));
      }
      System.out.println("Receive from client message=: " + builder);
      reader.close();
      socket.close();
      server.close();
    } catch (Exception e) {
      e.printStackTrace();
    }
 }
}
입출력 객체 닫기
마지막으로 자원의 정확한 방출을 확보하기 위해 IO 대상을 정확하게 닫아야 한다는 것을 잊어서는 안 된다.
하나의 예를 덧붙이다
여기서 우리는 socket을 사용하여 메아리 서버를 실현한다. 바로 서버가 클라이언트가 보낸 데이터를 클라이언트에게 전송하는 것이다.코드가 간단합니다.

import java.io.*;
import java.net.*;
public class EchoServer {
  public static void main(String args[]) {
    // declaration section:
    // declare a server socket and a client socket for the server
    // declare an input and an output stream
    ServerSocket echoServer = null;
    String line;
    DataInputStream is;
    PrintStream os;
    Socket clientSocket = null;
    // Try to open a server socket on port 9999
    // Note that we can't choose a port less than 1023 if we are not
    // privileged users (root)
    try {
      echoServer = new ServerSocket(9999);
    }
    catch (IOException e) {
      System.out.println(e);
    }
    // Create a socket object from the ServerSocket to listen and accept 
    // connections.
    // Open input and output streams
    try {
        clientSocket = echoServer.accept();
        is = new DataInputStream(clientSocket.getInputStream());
        os = new PrintStream(clientSocket.getOutputStream());
        // As long as we receive data, echo that data back to the client.
        while (true) {
         line = is.readLine();
         os.println(line);
        }
    } catch (IOException e) {
        System.out.println(e);
      }
    }
}
위의 코드를 컴파일하여 아래와 같은 요청을 하면 클라이언트가 요청한 데이터의 내용을 볼 수 있습니다.

15:00 $ curl http://127.0.0.1:9999/?111
GET /?111 HTTP/1.1
User-Agent: curl/7.37.1
Host: 127.0.0.1:9999
Accept: */*
총결산
클라이언트 - 서버 쪽 프로그래밍을 하는 것은 비교적 재미있고, 동시에 자바에서 socket 프로그래밍을 하는 것은 다른 언어(예를 들어 C)보다 간단하고 신속하게 작성해야 한다.
java.net 이 패키지에는 개발자가 네트워크 프로그래밍을 할 수 있도록 강력하고 유연한 클래스가 많이 포함되어 있으며, 네트워크 프로그래밍을 할 때 이 패키지 아래의 API를 사용하는 것을 권장합니다.동시에 Sun.*이 가방도 많은 네트워크 프로그래밍과 관련된 종류를 포함하고 있지만 이 가방 아래의 API를 사용하는 것을 권장하지 않습니다. 이 가방이 바뀔 수 있기 때문입니다. 그리고 이 가방은 모든 플랫폼에 포함될 수 없습니다.
이상은 Java Socket 자료를 정리하고 관련 지식을 계속 보충하는 것입니다. 본 사이트에 대한 지지에 감사드립니다!

좋은 웹페이지 즐겨찾기