JAVAベースのソケット単純なネットワークチャットプログラム

ネットワークプロセス間で通信する方法

ローカルプロセス間通信(IPC)の間に多くの方法がありますが、次の4つのカテゴリーでまとめることができます。

  • メッセージング(パイプ、FIFO、メッセージキュー)
  • 同期(ミューテックス、条件変数、読み書きロック、書き込みレコードファイルロック、セマフォ)
  • 共有メモリ(匿名と命名)
  • リモートプロシージャコール(SolarisのドアとSun RPC)

しかし、これらは、この資料の対象ではありません!私たちは、ネットワークのプロセス間通信方法を議論したいですか?主な問題は、一意論外プロセスやコミュニケーションを特定する方法です!ローカルで一意にPIDによるプロセスを識別することができますが、ネットワークは、それが動作しません。実際には、TCP / IPプロトコルスイートは、私たちはこの問題、ネットワーク上の一意に識別するホストネットワーク層の「IPアドレス」、およびトランスポート層一意のホスト(プロセス)を識別することができ、「プロトコル+ポート」アプリケーションを解決するために役立っています。したがって、他のプロセスと対話するためにこのフラグを使用することができ、プロセス、プロセス通信ネットワークを識別することができるネットワークに三重(IPアドレス、プロトコル、ポート)を使用。

プロセス間のネットワーク通信に、UNIX BSDソケット(ソケット)TLIとUNIXシステムV(それが除去されている)のTCP / IPプロトコル・アプリケーション・プログラミング・インターフェースは、一般的に使用されるアプリケーションを使用して。今のところ、ほとんどすべてのアプリケーションがソケットに基づいていますが、今のインターネットの時代ですが、ネットワークのプロセス間通信は、「すべてはソケット」理由である、どこにでもあります。

TCPの概要

  1.TCPはじめに

    A> TCPプロトコル:TCPプロトコル、伝送制御プロトコル(英語:と略記伝送制御プロトコル:TCP)は、コネクション指向の、信頼性の高いバイトストリームプロトコルベースの通信であります

    1.コネクション型:コールモデルのような第一のコネクタ、及びその後の通信は、

    2.信頼性の高い、UDPに対して、TCPは伝送の信頼性を保証するために、より信頼性の高い伝達機構(コネクション型機構、送信応答機構)によってTCPシーケンスであります

    3.バイトストリームに基づいて、UDPは、UDPソケットを作成 - DGRAM:データグラムベースの通信システムを、各送信されたデータは、ターゲット・ホスト、ポート番号のIPアドレスを含む、独立したエンティティであり、コンテンツデータが送信されます

    B> 3つの段階TCP通信

    ベースの接続指向:サーバーとの接続を確立するために、1。

            2.送受信データ

  

 

 

          3.接続を閉じます

  2.TCPの特長

    A>コネクション指向

    1.最初の接続を確立し、その後、通信

    2.TCP接続は1対1または1対多でもよくUDP、UDP適切な放送用番組

    A>信頼性の高い伝送:TCPはUDPの送信よりも信頼性が高いデータを保護するためのメカニズムのシーケンスにより、

    1.送信応答機構

    2.タイムアウト再送メカニズム

    3.エラーチェック

    4.フロー制御/輻輳管理

JavaSocketプログラミング

        Java環境では、ソケットは、プログラミング主にTCP / IPプロトコルに基づいてネットワークプログラミングを指します。

 

        ソケットのワークプロセスは、以下の4つのステップで構成されています。

  (1)ソケットを作成します。

  (2)入力/出力ストリームへのオープンソケット接続。

  (3)ソケット、リード/ライト動作のための特定のプロトコルに従いました。

  (4)閉じるソケット

 

JavaのSocketクラスは、2が含まれています:ソケット(クライアント)とのServerSocket(サーバー)

1)Socketクラス

    ソケットクラス:このクラスを実装クライアントソケット、ソケットは、2つのデバイス間の通信のエンドポイントを指します。コンストラクタ公共のソケット(文字列のホスト、int型ポート ): 指定されたホスト上のソケット接続オブジェクトと指定したポート番号を作成します。指定されたホストがnull、ループバックアドレスに指定したアドレスに相当します。
    メンバーの方法:

         公共のInputStreamのgetInputStream():このソケットの入力ストリームを返します。このScoketに関連するチャネルを有する場合、生成された操作入力ストリームの全ては、チャネルに関連付けられています。クローズ生成されたInputStreamが関連付けられているソケットを閉じます。

    公共のOutputStreamのgetOutputStream():このソケットの出力ストリームを返します。このScoketに関連するチャネルを有する場合、生成された操作のOutputStreamの全ては、このチャネルに関連付けられています。クローズ生成されたOutputStreamは、関連付けられたソケットを閉じます。
    公共のボイド近い():このソケットを閉じます。ソケットが閉じられると、それは再利用することはできません。閉じるこのソケットは、関連付けられたInputStreamとOutputStreamを閉じます。
    ます。public void shutdownOutput():無効ソケット出力ストリーム。以前に書き込まれたデータが出力ストリームを終了する、送信します。

 

 


  2)クラスのServerSocket
  のServerSocketクラス:このクラスを実装し、サーバソケット、オブジェクトは、ネットワーク上の要求を待っています。

  コンストラクタ

 

 

     公共のServerSocket(INTポート):ServerSocketオブジェクトを作成するときにこの構成方法では、特定のポート番号にバインドすることができ、ポート番号は、ポートパラメータです。

    設定例は、次のように:ServerSocketのサーバーは=新しいServerSocketを(6666);

  メンバー方法

    公共ソケット)が(受け入れ:リッスンし、接続を受け入れ、新しいSocketオブジェクトを返し、クライアントが通信するため。このメソッドは、
接続が確立されるまでブロックします。

詳細な接続を確立するために、TCP 3ウェイハンドシェイクでソケット

私たちは、「3ウェイハンドシェイク」そのやり取り3つのパケットへの接続を確立するTCP知っています。プロセスは、実質的に、以下:

  • クライアントはサーバSYN Jを送信します
  • クライアントにSYN K、およびSYN J確認ACK J + 1とサーバの応答
  • クライアントサーバの考えは、確認応答ACK K + 1を送信します

唯一の3ウェイハンドシェイクが完了しますが、この3ウェイハンドシェイクでそのいくつかの機能は、その中のソケットに発生するでしょうか?以下を参照してください。

image

 

从图中可以看出,当客户端调用connect时,触发了连接请求,向服务器发送了SYN J包,这时connect进入阻塞状态;服务器监听到连接请求,即收到SYN J包,调用accept函数接收请求向客户端发送SYN K ,ACK J+1,这时accept进入阻塞状态;客户端收到服务器的SYN K ,ACK J+1之后,这时connect返回,并对SYN K进行确认;服务器收到ACK K+1时,accept返回,至此三次握手完毕,连接建立。

客户端的connect在三次握手的第二个次返回,而服务器端的accept在三次握手的第三次返回。

 

socket中TCP的四次握手释放连接详解

上面介绍了socket中TCP的三次握手建立过程,及其涉及的socket函数。现在我们介绍socket中的四次握手释放连接的过程,请看下图:

image

 

图示过程如下:

  • 某个应用进程首先调用close主动关闭连接,这时TCP发送一个FIN M;
  • 另一端接收到FIN M之后,执行被动关闭,对这个FIN进行确认。它的接收也作为文件结束符传递给应用进程,因为FIN的接收意味着应用进程在相应的连接上再也接收不到额外数据;
  • 一段时间之后,接收到文件结束符的应用进程调用close关闭它的socket。这导致它的TCP也发送一个FIN N;
  • 接收到这个FIN的源发送端TCP对它进行确认。

这样每个方向上都有一个FIN和ACK。

Java的Socket库函数与Linux的Socket系统调用之间的区别:

Java通过JVM实现了优良的跨平台性,同一段写好的代码,移植到不同的操作系统上可直接执行,不受操作系统的限制,一处编译,到处执行,JAVA的SOCKET编程的底层原理是JVM将JAVA程序解析出来的参数传递给所对应的C++程序,由C++执行完之后回传给JAVA。

而LINUX自带的SOCKET编程只能再LINUX操作系统下使用,同时JAVA与LINUX的API也不一致。

一个小例子:

服务端代码:

package ray;
import java.io.*;
import java.net.*;
public class Server {
    private static ServerSocket server;

    public static void main(String[] args) throws IOException{
        server = new ServerSocket(1100);
        System.out.println("服务器启动成功,等待用户接入...");
        //等待用户接入,直到有用户接入为止,Socket对象表示客户端
        Socket client = server.accept();
        //得到接入客户端的IP地址
        System.out.println("有客户端接入,客户IP:" + client.getInetAddress());
        InputStream in = client.getInputStream();//从客户端生成网络输入流,用于接收来自网络的数据
        
        OutputStream out = client.getOutputStream();//从客户端生成网络输出流,用来把数据发送到网络上

        byte[] bt = new byte[1024];//定义一个字节数组,用来存储网络数据
        int len = in.read(bt);//将网络数据写入字节数组
        String data = new String(bt, 0 , len);//将网络数据转换为字符串数据
        System.out.println("来自客户端的消息:" + data);
        out.write("我是服务器,欢迎光临".getBytes());//服务器端数据发送(以字节数组形式)
        client.close();//关闭套接字
    }
}

客户端代码:

package ray;
import java.io.*;
import java.net.*;
public class Client {
    private static Socket client;

    public static void main(String[] args) throws UnknownHostException, IOException {
        client = new Socket("127.0.0.1", 1100);
        System.out.println("连接服务器成功");
        InputStream in = client.getInputStream();//从客户端生成网络输入流,用于接收网络数据
        OutputStream out = client.getOutputStream();//从客户端生成网络输出流,用来发送数据
        out.write("我是客户端,欢迎光临".getBytes());//客户端数据发送
        byte[] bt = new byte[1024];//定义一个字节数组,用来存储网络数据
        int len = in.read(bt);//将网络数据写入字节数组
        String data = new String(bt, 0 ,len);//将网络数据转换为字符串数据
        System.out.println("来自服务器的消息:" + data);
        client.close();//关闭套接字
    }
}

运行结果展示:

服务器端:

 

 

 

 

 

 

 

  

おすすめ

転載: www.cnblogs.com/zzydexiaowu/p/11988675.html