>  기사  >  Java  >  Java 네트워크 프로그래밍에 대한 경험

Java 네트워크 프로그래밍에 대한 경험

零下一度
零下一度원래의
2017-07-17 13:11:592509검색

최근에 Java 네트워크 프로그래밍을 배우고 있습니다. 들어본 적은 있지만 진지하게 이해한 적은 없습니다. 지난 며칠간 갑자기 관심이 생기고 정말 신기한 일이라는 생각이 들었습니다. 갑자기 구체적인 상황이 무엇인지 알고 싶었습니다. Commun 소켓은 일반적으로 "소켓"이라고 하며, IP 주소와 포트를 설명하는 데 사용됩니다. 통신 체인의 핸들입니다. 인터넷상의 호스트는 일반적으로 여러 서비스 소프트웨어를 실행하고 동시에 여러 서비스를 제공합니다. 각 서비스는 소켓을 열고 포트에 바인딩됩니다. 다른 포트는 다른 서비스에 해당합니다.

소켓은 휴대폰 소켓과 매우 유사합니다. 전국 전화망을 예로 들면, 통화 중인 두 당사자는 서로 통신하는 두 프로세스에 해당하며, 지역 코드는 해당 지역의 한 단위에 있는 스위치의 네트워크 주소와 동일하며, 호스트는 각 사용자에게 사무실 내 번호를 할당합니다. 사용자가 전화를 걸기 전에 먼저 전화를 보유해야 하며 이는 소켓을 신청하는 것과 동일하며 상대방의 번호를 알아야 하며 이는 상대방이 고정 소켓을 가지고 있는 것과 동일합니다. 그런 다음 상대방에게 전화를 겁니다. 이는 연결 요청을 하는 것과 같습니다. (상대방이 같은 지역에 있지 않으면 상대방의 지역 번호도 눌러야 하며, 이는 네트워크 주소를 제공하는 것과 같습니다.) 상대방이 존재하고 유휴 상태인 경우(다른 통신 호스트가 켜져 있고 연결 요청을 수락할 수 있는 것과 동일) 전화 수화기를 들고 두 당사자가 공식적으로 대화할 수 있으며 이는 성공적인 연결과 같습니다. 두 당사자 간의 통화 과정은 한쪽이 전화기에 신호를 보내고 다른 쪽이 전화기에서 신호를 받는 과정으로, 이는 소켓에 데이터를 보내고 소켓에서 데이터를 받는 것과 같습니다. 통화가 끝난 후 한 쪽에서 전화를 끊는 것은 소켓을 닫고 연결을 취소하는 것과 같습니다.


전화 시스템에서 일반 사용자는 통화 연결 과정, 음성 전송 과정 및 전체 전화 시스템의 기술적 세부 사항이 모두 로컬 전화와 상대방 전화 번호의 존재를 느낄 수 있습니다. 그에게 투명하며 이는 소켓 메커니즘과도 일치합니다. 매우 유사합니다. 소켓은 프로세스 통신을 위해 인터넷 통신 설비를 사용하지만, 통신 설비가 충분한 통신 능력을 제공할 수 있다면 통신 설비의 세부 사항에는 신경 쓰지 않습니다.

바이두 백과사전에 나오는 정의와 설명인데, 이전의 일부 설명이 너무 전문적인 용어가 많아 이해하기가 매우 어려웠던 것과는 달리 상당히 이해하기 쉽습니다.

소켓 통신 구현 단계:

  1. ServerSocket 및 소켓 생성
2. 소켓에 연결된 입력/출력 스트림 열기 3. 프로토콜(일반적으로 TCP/UDP)에 따라 소켓에서 읽기 및 쓰기 작업 수행 4. 입력/출력 스트림을 닫고 Socket

Socket 프로그래밍

을 닫습니다. 하나는 ServerSocket이고 다른 하나는 Socket입니다. 서버와 클라이언트는 Socket을 통해 연결을 맺고 통신을 할 수 있다. 먼저 ServerSocket은 서버 측의 특정 포트를 수신하여 클라이언트에 소켓이 있는 것을 확인하고 연결을 시도하면 해당 소켓의 연결 요청을 수락하고 서버 측에 해당 소켓을 설정하여 통신합니다. 그것으로. 이런 방식으로 두 개의 소켓이 있는데, 하나는 클라이언트용이고 다른 하나는 서버용입니다.

소켓 간의 통신은 실제로 매우 간단합니다. 서버는 소켓의 출력 스트림에 무언가를 쓰고 클라이언트는 소켓의 입력 스트림을 통해 해당 내용을 읽을 수 있습니다. Socket과 Socket 사이에는 양방향 연결이 있으므로 클라이언트는 해당 Socket 출력 스트림에 내용을 쓸 수도 있고, 그런 다음 서버의 해당 Socket 입력 스트림에서 해당 콘텐츠를 읽을 수도 있습니다.


다음은 클라이언트 읽기 쓰기와 서버 읽기 쓰기의 예입니다
Java 네트워크 프로그래밍에 대한 경험서버측 코드

public class Server {
public static void main(String args[]) throws IOException {
      //定义一个ServerSocket监听在端口8888上  
      int port = 8888; 
      int i=1; //连接计数
      //server尝试接收其他Socket的连接请求,
      ServerSocket server = new ServerSocket(port);  
      //server的accept方法是阻塞式的 ,即等待着客户端的请求
      Socket socket = server.accept();  
      System.out.println("连接"+i++);
      //跟客户端建立好连接,我们就可以获取socket的InputStream,从中读取客户端发过来的信息。  
      Reader reader = new InputStreamReader(socket.getInputStream());    
      char chars[] = new char[64];  
      int len;  
      StringBuilder sb = new StringBuilder();  
      String temp;  
      int index;  
      while ((len=reader.read(chars)) != -1) {  
         temp = new String(chars, 0, len);  
         if ((index = temp.indexOf("eof")) != -1) { //遇到eof时就结束接收  
            sb.append(temp.substring(0, index));  
            break;  
         }  
         sb.append(temp);  
      }  
      System.out.println("from client: " + sb);  
      //读完后写数据 
      Writer writer = new OutputStreamWriter(socket.getOutputStream());  
      writer.write("Hello Client:我是服务端输入数据"); 
      //释放资源
      writer.flush();  
      writer.close(); 
      reader.close();  
      socket.close();  
      server.close(); 
   }  
}

Output

주의사항

Java 네트워크 프로그래밍에 대한 경험

InputStream에서 데이터를 읽는 서버의 동작 입력 스트림에서 데이터를 읽지 않으면 클라이언트가 소켓 출력 스트림에 데이터를 쓰거나 소켓 출력 스트림을 닫을 때까지 프로그램이 그대로 유지됩니다. 물론 클라이언트의 소켓에도 마찬가지입니다.

  • 클라이언트가 입력 스트림에서 보낸 데이터를 읽은 다음 클라이언트의 출력 스트림에 데이터를 쓴 다음 해당 리소스 파일을 닫습니다. 실제로 위의 코드는 입력 스트림에서 데이터를 읽는 것이 차단 작업이기 때문에 예상대로 실행되지 않을 수 있습니다. 위의 while 루프에서는 데이터를 읽을 때 루프 본문이 실행되고 그렇지 않으면 차단되므로 후속 작업이 수행됩니다. 쓰기 작업은 절대 실행되지 않습니다. 이 경우 일반적으로 끝 표시에 동의합니다. 클라이언트가 보낸 데이터에 끝 표시가 포함되어 있으면 현재 데이터가 전송되었음을 의미합니다. 루프.

  • 在上述代码中,当服务端读取到客户端发送的结束标记,即“eof”时就会结束数据的接收,终止循环,这样后续的代码又可以继续进行了。

客户端代码

public class Client {
 public static void main(String args[]) throws Exception {  
      //为了简单起见,所有的异常都直接往外抛  
      String host = "192.168.74.1";  //要连接的服务端IP地址  
      int port = 8888;   //要连接的服务端对应的监听端口  
      //与服务端建立连接  
      Socket client = new Socket(host, port);  
      //建立连接后就可以往服务端写数据了  
      Writer writer = new OutputStreamWriter(client.getOutputStream());  
      writer.write("Hello ,我是客户端输入数据");
      writer.write("eof"); 
      writer.flush();//写完后要记得flush  
      //读取来自服务端数据
      Reader reader = new InputStreamReader(client.getInputStream());  
      char chars[] = new char[64];  
      int len;  
      StringBuffer sb = new StringBuffer();  
      String temp;  
      int index;  
      while ((len=reader.read(chars)) != -1) {  
         temp = new String(chars, 0, len);  
         if ((index = temp.indexOf("eof")) != -1) {  
            sb.append(temp.substring(0, index));  
            break;  
         }  
         sb.append(new String(chars, 0, len));  
      }  
      System.out.println("from server: " + sb);
      writer.close(); 
      reader.close();  
      client.close();  
   }  
}

输出

Java 네트워크 프로그래밍에 대한 경험

注意点

  • 过程:先是给服务端发送了一段数据,之后读取服务端返回来的数据,跟之前的服务端一样在读的过程中有可能导致程序一直挂在那里,永远跳不出while循环,解决方法和服务端一样,用一个结束标志。

  • 对于客户端往Socket的输出流里面写数据传递给服务端要注意一点,如果写操作之后程序不是对应着输出流的关闭,而是进行其他阻塞式的操作(比如从输入流里面读数据),记住要flush一下,只有这样服务端才能收到客户端发送的数据,否则可能会引起两边无限的互相等待。在稍后讲到客户端和服务端同时读和写的时候会说到这个问题。

위 내용은 Java 네트워크 프로그래밍에 대한 경험의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

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