TCPプロトコルに基づくネットワークソケットプログラミング(javaはC / S通信を実現します)

目次

ゼロ、1024の特別な贈り物

1.はじめに:TCP原則の概要

2、ソケットプログラミング通信

3. TCPサーバー側(特定のコード)

4、TCPクライアント(特定のコード)

5.コミュニケーション効果のデモンストレーション

6.「クリエイティブ」ロボット:1億ドル相当のAIコアコード(特定のコード)

セブン、ついに


ゼロ、1024の特別な贈り物

1024、1GB、素晴らしい、さあ!

1.はじめに:TCP原則の概要

まず第一に、記事の完全性を確保するために、TCPの理論的原則を説明する必要がありますが、これは少し退屈です。

TCP(Transmission Control Protocol、Transmission Control Protocol)は、接続指向で信頼性の高い、バイトストリームベースのトランスポート層通信プロトコルですTCPは、複数のネットワークアプリケーションをサポートする階層化されたプロトコル階層に適応するように設計されています。言い換えると、TCPは信頼性の低いインターネットネットワーク上で信頼性の高いエンドツーエンドのバイトストリームを提供するよう特別に設計された伝送プロトコルです異なるが相互接続されたコンピューター通信ネットワークに接続されたホストコンピューターのペアプロセスは、信頼性の高い通信サービスを提供するためにTCPに依存しています。

上記のTCPの特性は、UDPとの明らかな違いでもあります。UDP(User Datagram Protocol)は、接続がなく、信頼性が低く、バイト以外のストリーム伝送通信プロトコルです具体的な違いは、前の記事と比較できます。

[ UDPプロトコルに基づくネットワークソケットプログラミング(javaのC / S通信の場合)  ] [ https://blog.csdn.net/Charzous/article/details/109016215 ]

次に、「スリーウェイハンドシェイク」はよく知られた言葉であり、TCP接続を確立するための重要なプロセスです。多くの記事には詳細な解釈があり、この記事はこの原則の詳細な記録であり、Javaを使用してTCP Socketネットワーク通信を実現します。これには、C / Sソフトウェアアーキテクチャのプログラミング、実践に偏った、さらに興味深いものが含まれます。

2、ソケットプログラミング通信

この記事では、ソケットプログラミングにJavaを使用します。JavaのTCP / IPソケットプログラミングは、基本的な詳細をカプセル化します。プログラミングモデルを次の図に示します。

上から順に、TCPベースの通信にはサーバーサーバーとクライアントクライアントが必要です。

まず、接続を確立します2つの間の通信のために両端にソケットソケットがあります。クライアントは、接続するソケットを作成するようにサーバーに要求を送信します。サーバーは、クライアントによって開始された要求をいつでも監視し、クラックされたソケットを受信して​​作成します。

次に、通信を開始しますサービスとクライアントの入力ストリームと出力ストリームは相互に通信します。論理的には、通信プロセスの両側に2つのストリーム(出力ストリームと入力ストリーム)があることが理解できます。論理的には、2つのストリームは、2つの通信パイプの全二重通信モードとして理解できます。1つは反対側にデータを送信するために使用され、もう1つは反対側からデータを受信するために使用されます。

最後に、通信を終了しますクライアントは、サーバーにアクセスすると終了し、Socketおよび関連リソース(入力ストリームと出力ストリームなど)を切断して閉じます。サーバーはクライアントのステータスを監視し、Socketなどの接続を閉じます。

通信ルールを確立します。

サーバーとクライアントは、通常の通信を確保するために同じルールに同意する必要があります。プログラムの設計後、私たちは同意しました:

  1. クライアントはサーバーに接続します。接続が成功すると、サーバーは最初にウェルカムメッセージをクライアントに送信します。

  2. クライアントプログラムがサーバーに情報を送信するたびに、サーバーはその情報を受信して​​クライアントに送り返し、クライアントはその情報を受信して​​表示します。

  3. クライアントが「さようなら」を送信すると、会話は終了します。

3. TCPサーバー側(特定のコード)

最初のステップは、サーバーソケットを作成することです。

クラスメンバー変数:ServerSocket serverSocket、モニターポート番号ポート;

    private int port =8008;//服务器监听窗口
    private ServerSocket serverSocket;//定义服务器套接字

    public TCPServer() throws IOException{
        serverSocket =new ServerSocket(port);
        System.out.println("服务器启动监听在"+port+"端口...");

    }

2番目のステップは、入力および出力ストリームメソッドを定義することです。

    private PrintWriter getWriter(Socket socket) throws IOException{
        //获得输出流缓冲区的地址
        OutputStream socketOut=socket.getOutputStream();
        //网络流写出需要使用flush,这里在printWriter构造方法直接设置为自动flush
        return new PrintWriter(new OutputStreamWriter(socketOut,"utf-8"),true);
    }

    private BufferedReader getReader(Socket socket) throws IOException{
        //获得输入流缓冲区的地址
        InputStream socketIn=socket.getInputStream();
        return new BufferedReader(new InputStreamReader(socketIn,"utf-8"));
    }

 3番目のステップ、サーバーのコア:

//单客户版本,每次只能与一个用户建立通信连接
public void Service(){
    while (true){
        Socket socket=null;
        try {
            //此处程序阻塞,监听并等待用户发起连接,有连接请求就生成一个套接字
            socket=serverSocket.accept();

            //本地服务器控制台显示客户连接的用户信息
            System.out.println("New connection accepted:"+socket.getInetAddress());
            BufferedReader br=getReader(socket);//字符串输入流
            PrintWriter pw=getWriter(socket);//字符串输出流
            pw.println("来自服务器消息:欢迎使用本服务!");

            String msg=null;
            //此处程序阻塞,每次从输入流中读入一行字符串
            while ((msg=br.readLine())!=null){
                //如果用户发送信息为”bye“,就结束通信
                if(msg.equals("bye")){
                    pw.println("来自服务器消息:服务器断开连接,结束服务!");
                    System.out.println("客户端离开。");
                    break;
                }
                pw.println("来自服务器消息:"+msg);
            }
        }catch (IOException e){
            e.printStackTrace();
        }finally {
            try {
                if (socket!=null)
                    socket.close();//关闭socket连接以及相关的输入输出流
            }catch (IOException e){
                e.printStackTrace();
            }
        }
    }
}

 コードの重要な分析は非常に明確で理解しやすいものです。サーバーによって提供されるサービスがWhile(true)に配置されていることがわかります。これは、サーバープログラムを常に実行する必要があるため、処理コードは通常、while(true)などの無限ループに配置されます。TCPServerは1回実行され、それ自体を終了できません。実行して、その操作を終了するには、強制的に閉じることしかできません(たとえば、IDE環境で)。

4、TCPクライアント(特定のコード)

最初のステップは、クライアントソケットを作成し、クラス構築メソッドを定義し、入力ストリームと出力ストリームを実装することです。

    private Socket socket;

    private PrintWriter pw;
    private BufferedReader br;

    public TCPClient(String ip, String port) throws IOException{
        //主动向服务器发起连接,实现TCP三次握手
        //不成功则抛出错误,由调用者处理错误
        socket =new Socket(ip,Integer.parseInt(port));

        //得到网络流输出字节流地址,并封装成网络输出字符流
        OutputStream socketOut=socket.getOutputStream();
        //参数true表示自动flush数据
        pw=new PrintWriter(new OutputStreamWriter(socketOut,"utf-8"),true);

        //得到网络输入字节流地址,并封装成网络输入字符流
        InputStream socketIn=socket.getInputStream();
        br=new BufferedReader(new InputStreamReader(socketIn,"utf-8"));

    }

2番目のステップは、ネットワーク通信の送受信方法を実装することです。

    public void send(String msg){
        //输出字符流,由socket调用系统底层函数,经网卡发送字节流
        pw.println(msg);
    }

    public String receive(){
        String msg=null;
        try {
            //从网络输入字符流中读取信息,每次只能接受一行信息
            //不够一行时(无行结束符),该语句阻塞
            //直到条件满足,程序往下运行
            msg=br.readLine();
        }catch (IOException e){
            e.printStackTrace();
        }
        return msg;
    }

 3番目のステップは、外部呼び出しのネットワーク接続を閉じる方法を定義することです。

    public void close(){
        try {
            if (socket!=null)
                socket.close();
        }catch (IOException e){
            e.printStackTrace();
        }
    }

 TCP接続の解放には、2MSL後に解放する必要がある「4方向ハンドシェイク」もあります。具体的なプロセスは次のとおりです。

5.コミュニケーション効果のデモンストレーション

GIFアニメーションデモ:

6.「クリエイティブ」ロボット:1億ドル相当のAIコアコード(特定のコード)

このパートでは、次のような効果を持つ「チャットボット」を実装します。

それを達成する方法を知るのが待ちきれません!「1億相当のAIコアコード」と呼べる!

それでおしまい!

 それを売らないでください、ただ1行のコード!

msg=msg.replace("?","!").replace("?","!").replace("吗","").replace("吗?","");

 具体的には、ロボットの反応を知りたい場合は、コードを自分で調整することができます。

セブン、ついに

この記事は、この原則に関する詳細な記録であり、Javaを使用してTCP Socketネットワーク通信を実現します。これには、C / Sソフトウェアアーキテクチャのプログラミング、偏った実践などが含まれます。注意深く読んだ友人は、サーバー側のコア部分に、プログラムがシングルユーザー、つまりシングルスレッド通信のみをサポートしていることを示すコメントの行があることに気付くでしょう。試してみることができます。別のクライアントを開いてサービスに接続する場合、それはシングルスレッドブロッキングが原因です。プログラムがスタックしています。

この問題の鍵は、サーバーとクライアントが相互に通信ルールに同意しているという事実にあります。そうしないと、問題が発生する可能性があります。たとえば、クライアント接続が成功した後にサーバーがクライアントにメッセージを送信しない場合、クライアントはウェルカムメッセージステートメントを読み取ります。コンテンツが読めない場合はブロックされます。シングルスレッドのため、プログラム全体でもスタックします。この問題を解決するには、次の更新を待ちます。

さらに、UIインターフェイスの設計は、前のブログを参照できます:[ UDPプロトコルに基づくネットワークソケットプログラミング(JavaのC / S通信ケース)  ] [ https://blog.csdn.net/Charzous/article/details/109016215 ]


私のCSDNブログ:https://blog.csdn.net/Charzous/article/details/109260488

おすすめ

転載: blog.csdn.net/Charzous/article/details/109260488