바이오 초기 네트워크 프로그래밍, NIO

       당신 흔들며 네와 세 방향 핸드 셰이크의 요청받을 수 있습니다 인터뷰에 대해 얘기하기 전에?

       B에 대한 전송이 A를 B로 전송 도시의 도시 문자를 가정, B는 분산의 문제가 A, B는 초기 통신을 설정, 수신됩니다. 세 파는이 수신 B의 전송 능력을 확인하고, 접속을 실시한 정상 증명하는 것이다.

        첫 번째 핸드 : A는 B에 보낼 때, B는 문자, 도시 B를 이해하는이 시간, 전송 용량 및 도시 괜찮 용량 B 도시를 수신 받는다.

        두 번째 악수 : B가 A를 보낼 때 A는 동안, 편지, 다음 도시 A가 이해할 수, 전송 용량 및 도시 B 괜찮 도시의 수신 능력, 플러스 이전의 전송을받은 또한 수신 B시의 (자신의) 신호 기능과 용량을 알고있는 양측은 OK입니다 알고 있지만,이 (가)가 처음이지만 있기 때문에 B는 의아해에 해당하는, 괜찮습니다 자신의 능력을받는 신호 기능은 OK이지만, 신호 기능과 도시의 능력 타운 B (자신을)받지 않는 방법을 알고, 그래서 세 번째 핸드 셰이크가 필요하지 않습니다.

        세 번째 악수 : B, 당신은 B를 (그 신호 기능) 알고 양측이 알고 있기 때문에 수신 기능이 도시가 너무 많이, 또한, 그것은 Taoxintaofei 하이 엔드 확인되면 B로 발행 한 영수증 그것은 심지어 이론적 근거. 첫 번째 통신의 설립을 완료합니다.

       아마 다음 그림에서 볼 흐름 :

TCP 세 방향 핸드 쉐이크 프로토콜 연결 후에는 결론을 내릴 수있다
먼저 악수 A -> B A는 결론을 내렸다 : 내가 좋아 보내는 경우, 확실하지가 모르는 무엇 
B 결론 : 뚱뚱한 B 가까운 확인을 
두 번째 핸드 셰이크 B ->를 헤어 콜렉션 B를 더하여 제 1 송신의 도입은 소득 확인하기 전에 B를 보낼 수 있으므로 확인 AB 있습니다 나는 전송 및 수신을 이해할 수 있습니다 결론을 그릴 수 있습니다
B는 결론을 내렸다 B는 헤어 가까운 확인에 따라 처음 하지만 성공과를 받아들이는 자신의 능력을 보낼지 여부를 알 수 없습니다
세 번째 악수 A -> B B는 수신 한 후 전송 된 B는 메시지가 입증 될 수있다 : A와 B를 수신 확인 신호 자체 기능 및 용량

사실,이 내가 모듈에 참여하기 전에해야 할 일을했을, 로그 다운로드 함수를 작성 담당 한, 그 구현을 완료하는 B / S 구조의 사용은 소켓 프로그래밍의 사용을 달성하기 위해, 멀티 스레딩의 같은 조합이다 기능. 서버로 장치 (소스 로그)에서의 InputStream 클래스는 방법을 차단 () 읽을 수 있기 때문에 클라이언트 (재전송 요청)와 같은 브라우저, 통신을 형성, 그래서가, 하나 개의 요청마다 머리카락 멀티 스레드 또는 스레드 풀을 사용하는 것이 필요하다 따라서 새 스레드를 사용하여 서로 간섭, 여기에 운영 위에서 내가 (채팅 같은) 아날로그 약간의 데모입니다.

클라이언트 코드 :

package NIO.clientpkg;

import java.io.PrintStream;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketAddress;
import java.util.Scanner;


/**
 *目的:客户端向服务端发送请求服务端接受请求,并回应相同的信息,一旦客户端写入bye,则结束本次操作
 */
public class Client {


    public static void main(String[] args) throws Exception{
        SocketAddress socketAddress = new InetSocketAddress ("localhost",9001);
        Socket socket = new Socket ();
        socket.connect (socketAddress,1000*5);//5second
        //发送输入的数据  以打印流的方式
        PrintStream out = new PrintStream (socket.getOutputStream ());
        //接受服务端传来的数据,将其保存在打印流中
        Scanner in = new Scanner (socket.getInputStream ());
        System.out.println ("请输入你要发送给服务端的信息");
        Scanner scanner = new Scanner (System.in);
        while (true){
            //发送消息
            if (scanner.hasNext ()){ //hasNext和next都是半阻塞的方法,会一直处于等待,所以必须用一个变量来接收
                //输入的消息
                String str = scanner.next ();
                out.println (str);
                if (str.equals ("bye")){
                    System.out.println ("服务端发过来的消息:" + in.next ());
                    break;//不能立即退出,会导致客户端退出服务端还处于连接丢包
                }
                //接收消息
                if (in.hasNext ()){
                    System.out.println ("服务端发过来的消息:" + in.next ());
                }
            }
        }
        socket.close ();
        scanner.close ();
        in.close ();
        out.close ();
    }

}

서버 코드 :

package NIO.serverpkg;

import java.io.IOException;
import java.io.PrintStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 /**
 *目的:客户端向服务端发送请求服务端接受请求,并回应相同的信息,一旦客户端写入byebye,则结束本次操作
 *TCP服务器端依次调用socket()、bind()、listen()之后,就会监听指定的socket地址了。
 *TCP客户端依次调用socket()、connect()之后就向TCP服务器发送了一个连接请求。TCP服务器监听到这个请求之后,
 *就会调用accept()函数取接收请求,这样连接就建立好了。之后就可以开始网络I/O操作了,即类同于普通文件的读写I/O操作。
 */
public class Server2 {

    private static ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor (10,50,5, TimeUnit.SECONDS,new LinkedBlockingQueue<> (100));

    public static void main(String[] args) throws Exception{

        //通常服务端在启动的时候回绑定一个众所周知的地址(ip+端口)用于提供服务,客户就可以通过它来接连服务器;而客户端就不用指定,有系统自动
        //分配一个端口号和自身的ip地址组合。这就是为什么通常服务器端在listen之前会调用bind(),而客户端就不会调用,而是在connect()时由系统随机生成一个。
        ServerSocket serverSocket = new ServerSocket (9001);//初始化socket,对端口进行绑定,并且对端口进行监听
        //这里要用一个while来接受不断发过来的请求,,但是因为accept会阻塞,故这里必须用线程
        while (!serverSocket.isClosed ()){
            Socket socket = serverSocket.accept ();//侦听并接受到此套接字的连接。此方法在进行连接之前一直阻塞。这应该是一个一直在进行的新线程,因为她面对的可能是诸多追求者
            if (socket.isConnected ()){
                System.out.println ("连接成功男朋友为:" + socket.toString ());
            }
            threadPoolExecutor.execute (() -> {
                try {
                    PrintStream out = new PrintStream (socket.getOutputStream ());//发送输入的数据  以打印流的方式
                    Scanner in = new Scanner (socket.getInputStream());//扫描流负责接受客户端发来的请求,一直不断变化的,因为socket是不断变化的
                    while (true){
                        if (in.hasNext ()){//阻塞的方法 inputStream类的read()方法
                            String str = in.next ();
                            System.out.println ("接受到客户端发来的信息:" + str);
                            out.println (str);//接收到消息  并回复同等内容
                            if (str.equals ("bye")){
                                break;
                            }
                        }
                    }
                    out.close ();
                    in.close ();
                    socket.close ();
                } catch (IOException e) {
                    e.printStackTrace ();
                }

            });
        }
        System.out.println ("结束服务端");
        serverSocket.close ();

    }

}

서버와 두 개의 클라이언트를 시작, 클라이언트가 서버에 전송 : 나는 CLIENT2, 나는 client2_1 :

여담 :

우리 모두는 TCP 소켓이 본 계약을 준수하는 것입니다 알고있는 브라우저가 내 서버 작업에 액세스하는 경우 그? 우리의 시험 : 브라우저가 클라이언트 요청 께서 나를 보내신 것을 분명 HTTP 요청을 요청하지만 프로토콜이 일치하지 않기 때문에 브라우저에 대한 응답이 실제로 유효하지 않기 때문에 그렇게 만 고정 된 형식으로 반환해야, 분명히 가능하지 클라이언트에 데이터 (HTTP 프로토콜에 기반)이 될 수 있습니다.

코드 (리턴 HTTP 형식) 재 작성 :

package NIO.serverpkg;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;

public class ServerHttp {


    public static void main(String[] args) throws Exception{

        ServerSocket serverSocket = new ServerSocket (9001);
        while (!serverSocket.isClosed ()){
            Socket socket = serverSocket.accept ();
            if (socket.isConnected ()){
                System.out.println ("连接成功男朋友为:" + socket.toString ());
            }
            InputStream in = socket.getInputStream ();
            BufferedReader reader = new BufferedReader(new InputStreamReader (in, "utf-8"));
            String msg = "";
            while ( (msg = reader.readLine () ) != ""){
                System.out.println (msg);
                if (msg.length () == 0){
                    break;
                }
            }
            System.out.println("收到数据,来自:"+ socket.toString());
            OutputStream out = socket.getOutputStream ();
            out.write("HTTP/1.1 200 OK\r\n".getBytes());
            out.write("Content-Length: 11\r\n\r\n".getBytes());
            out.write("Hello World".getBytes());
            out.flush();
        }
        System.out.println ("结束服务端");
        serverSocket.close ();

    }

}

다음과 같이 HTTP 형식은 다음과 같습니다

위의 그것을 증명하는 것입니다에서, 본론, 멀티 스레드 또는이 디자인은 동시에 높은로, 문제가 스레드 풀을 고정, 상황을 나타납니다 스레드가 충분하지 않습니다 및 스레딩 작업을 소모 속한 비즈니스 로직 io를하거나 장기적인 직업은 아니다 연결이 닫힐 때, 경우에 스레드가 나타납니다 정도는 성능 문제에 상승 할 수 있어야하고 그 해결 방법?

NIO의 주제를 소개

 

추천

출처blog.csdn.net/qq_40826106/article/details/82665716