>  기사  >  Java  >  Java Socket 통신 분석에 대한 심층적인 이해

Java Socket 통신 분석에 대한 심층적인 이해

黄舟
黄舟원래의
2017-03-07 10:21:121725검색

이 기사에서는 주로 Java 소켓에 대한 심층적인 이해를 소개합니다. Java의 네트워크 통신은 소켓을 통해 구현됩니다. 소켓은 ServerSocket과 Socket의 두 가지 범주로 구분됩니다.

간략한 설명

Java의 소켓은 일반 소켓과 NioSocket의 두 가지 유형으로 나누어집니다.

소켓을 두 도시를 오가는 교통수단으로 비유할 수 있는데, 두 도시를 오가는 교통수단은 다양하며, 각 교통수단에도 해당되는 특징이 있습니다. 교통 규칙. 소켓에도 동일하게 적용되며 많은 유형이 있습니다. 대부분의 경우 안정적인 통신 프로토콜인 TCP/IP 스트림 소켓을 사용합니다. (TCP/IP와 UDP의 비교)

Java의 네트워크 통신은 Socket을 통해 구현되며, Socket은 ServerSocket과 Socket의 두 가지 범주로 구분됩니다. ServerSocket은 서버측에서 accept 메소드를 통해 요청을 수신하는 데 사용됩니다. . 소켓은 요청 후에 반환됩니다. 소켓은 데이터 전송을 구체적으로 완료하는 데 사용됩니다. 클라이언트는 소켓을 직접 사용하여 요청을 시작하고 데이터를 전송합니다.

ServerSocket 사용은 세 단계로 나눌 수 있습니다.

1. ServerSocket을 만듭니다. ServerSocket의 구성 방법은 총 5가지가 있으며 일반적으로 ServerSocket(int port)을 사용하며 포트번호(port)만 필요하다.

2. 생성된 ServerSocket의 accept 메서드를 호출하여 수신합니다. accept 메서드는 차단 방법입니다. 즉, accept 메서드를 호출한 후 프로그램이 중지되고 연결 요청을 기다리며, 요청이 수신될 때까지 프로그램이 계속되지 않습니다. 요청을 받으면 accept 메소드는 Socket을 반환합니다.

3. accept 메서드에서 반환된 소켓을 사용하여 클라이언트와 통신합니다.

Chestnut

클라이언트:

package IO;

import java.io.*;
import java.net.Socket;
import java.util.Date;

/**
 * Created by zhengbin06 on 2017/2/2.
 */
public class Client {
  public static void main(String[] args) {
    String msg = "Client Data";
    try {
      Socket socket = new Socket("127.0.0.1", 9090);

      // 先写、再读
      PrintWriter printWriter = new PrintWriter(socket.getOutputStream());
      // 发送数据
      printWriter.println(msg);
      printWriter.flush();
      // 获得服务端返回的数据
      BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
      String line = bufferedReader.readLine();
      System.out.println("received from server: " + line + "\ttime=" + new Date().getTime());
      // 关闭资源
      printWriter.close();
      bufferedReader.close();
      socket.close();
    } catch (IOException e) {
      e.printStackTrace();
    }
  }
}

서버:

package IO;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Date;

/**
 * Created by zhengbin06 on 2017/2/2.
 */
public class Server {
  private static Socket socket = null;
  private static ServerSocket serverSocket = null;
  public static void main(String[] args) throws IOException {
    BufferedReader bufferedReader = null;
    PrintWriter printWriter = null;
    try {
      // 创建一个ServerSocket监听9090端口
      serverSocket = new ServerSocket(9090);
      while (true) {
        System.out.println("开始等待请求。。。。");
        // 等待请求
        // 监听并接受到此套接字的连接。此方法在连接传入之前一直阻塞。
        socket = serverSocket.accept();
        System.out.println("接收到请求:" + socket.toString() + "\ttime=" + new Date().getTime());
        // 接收到请求后使用socket进行通信, 创建BufferedReader用于读取数据
        bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        String line = bufferedReader.readLine();
        System.out.println("received from client: " + line + "\ttime=" + new Date().getTime());
  
        // 创建PrintWriter, 用于发送数据
        printWriter = new PrintWriter(socket.getOutputStream());
        printWriter.println("received data: " + line + "\ttime=" + new Date().getTime());
        printWriter.flush();
      }
    } finally {
      // 关闭所有资源
      bufferedReader.close();
      printWriter.close();
      socket.close();
      serverSocket.close();
    }
  }
}

세부정보

요청 수신:

새 소켓이 생성될 때 요청이 오면 이 연결에 대한 새로운 소켓 데이터 구조가 생성됩니다. 소켓 데이터에 대한 정보에는 정식 요청 소스 주소와 포트의 주소와 포트가 포함됩니다. 새로 생성된 이 데이터 구조는 ServerSocket 인스턴스의 뛰어난 연결 데이터 구조 목록과 연결됩니다. 서버의 해당 소켓 인스턴스는 현재 생성되지 않았으므로 클라이언트와의 3방향 핸드셰이크가 완료될 때까지 서버의 소켓 인스턴스는 반환되지 않으며 소켓 인스턴스에 해당하는 데이터 구조는 반환되지 않습니다. 완료됨 목록의 이동이 목록에서 수행됩니다.

데이터 전송:

연결이 성공적으로 설정되면 서버와 클라이언트 모두 소켓 인스턴스를 갖게 되며 각 소켓 인스턴스에는 InputStream 및 OutputStream이 있습니다. 그리고 이 두 객체를 통해 데이터를 교환합니다.

네트워크 I/O는 바이트 스트림으로 전송된다는 점을 알아야 합니다. 소켓 객체를 생성할 때 운영 체제는 데이터 쓰기 및 읽기를 위해 각각 특정 크기의 버퍼 영역을 할당합니다. 이 캐시 영역을 통해 완료되었습니다.

쓰기 쪽에서는 OutputStream에 해당하는 SendQ 대기열에 데이터를 씁니다. 대기열이 가득 차면 데이터는 RecvQ인 경우에는 InputStream의 RecvQ 대기열로 전송됩니다. 이 시점에서 가득 차면 RecvQ 대기열이 SendQ에서 보낸 데이터를 수용할 수 있는 충분한 공간을 가질 때까지 OutputStream의 쓰기 메서드가 차단됩니다. 그 과정은 아래 그림과 같습니다.

위 내용은 Java Socket 통신 분석에 대한 심층적인 이해입니다. PHP 중국어 웹사이트(www.php.cn)에 주목하세요!


성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.