1。TCP/IPの紹介
TCP/IPプロトコルファミリは、インターネットで使用されるプロトコルであり、独立したプライベートネットワークでも使用できます。
TCP/IPプロトコルファミリには、IPプロトコル、TCPプロトコル、UDPプロトコルが含まれます。
IPプロトコルはIPアドレスを使用してパケットを配布しますが、それは最良のエフォルトサービスであり、パケットは失われたり、故障したり、繰り返される場合があります。 TCPおよびUDPプロトコルは、IPプロトコルにポート番号を追加し、2つのホストのアプリケーション間の透明な接続を確立します。
違いは、TCPプロトコルがIPレイヤーエラーを修正し、ハンドシェイクメッセージを介してホスト間の接続を確立することです。
次に、メッセージにシリアル番号を追加することにより、メッセージのエラーが復元されます。 UDPはIPプロトコルを拡張するだけです。
ホスト間ではなく、アプリケーション間で動作します。
IPアドレスに関しては、ホストには複数のネットワークインターフェイスを持つことができ、1つのインターフェイスに複数のアドレスを持つことができます。
一部のIPアドレスには特別な用途があります。
A.ループバックアドレス:127.0.0.1は、主にテストに使用されるループバックインターフェイスに常に割り当てられます。
B.プライベートアドレス:10、192.168、172。(16-31)、プライベートネットワークに使用。 NATデバイスがメッセージを転送すると、1つのインターフェイス内のメッセージのプライベートアドレスポートペアを別のインターフェイスのパブリックアドレスポートペアにマップします。これにより、小さなグループのホストグループがIPアドレスペアを共有できます。
C.マルチキャストアドレス:最初の数字は224〜239です。
2。ソケットの基本
1。アドレスの取得
public static void main(string [] args){try {enumeration <networkinterface> interfaces = networkinterface.getNetworkInterfaces(); while(interfaces.hasMoreElements()){networkInterface iface = interfaces.nextelement(); System.out.println( "interface:" + iface.getName()); Enumeration <InetAddress> addrlist = iface.getinetAddresses(); if(!addrlist.hasmoreElements())System.out.println( "no address"); while(addrlist.hasmoreElements()){inetAddress address = addrlist.nextelement(); system.out.println( "address:" + address.gethostaddress()); }}} catch(socketexception e){e.printstacktrace(); }}2.TCPインスタンスプログラム
クライアント側に文字列を送信するために1つのwrite()メソッドのみが使用されますが、サーバー側は複数のブロックからこの情報を受信することもできます。サーバーが返されるときにフィードバック文字列がブロックに保存されている場合でも、TCPである可能性があります
プロトコルは複数の部分に分割されます。
tcpechoclienttest.java
public static void main(string [] args)throws ioexception {string server = args [0]; byte [] data = args [1] .getBytes(); int port = 7;ソケットソケット= new Socket(サーバー、ポート); system.out.println( "server ..."); inputstream in = socket.getinputStream(); outputStream out = socket.getOutputStream(); out.write(data); int totalbytesrcvd = 0; int bytesrcvd; while(totalbytesrcvd <data.length){if((bytesrcvd = in.read(data、totalbytesrcvd、length.length -totalbytesrcvd)== -1)新しいsocketexception( "接続閉じた"); totalbytesrcvd += bytesrcvd; } system.out.println( "受信:" + new String(data)); socket.close(); }tcpechoservertest.java
Private static final int bufsize = 32; public static void main(string [] args)throws ioexception {serversocket serversocket = new Serversocket(7); int recvmsgsize; byte [] receivebuf = new byte [bufsize]; while(true){socket socket = serversocket.accept(); system.out.println( "remote" + socket.getRemoteSocketAddress() + "at local" + socket.getLocalsockateDdress())から "client" + " +" + " inputstream in = socket.getinputStream(); outputStream out = socket.getOutputStream(); while((recvmsgsize = in.read(receiveBuf))!= -1){out.write(receivebuf、0、recvmsgsize); } socket.close(); }}新しいソケットは、ローカルポートを指定せずにリモートサーバーが耳を傾けるポート番号を指定しているため、デフォルトのアドレスと使用可能なポート番号が使用されることに注意してください。私のマシンのクライアントポートは4593で、サーバーのポート7に接続されています。
3。UDPインスタンスプログラム
なぜUDPプロトコルを使用するのですか?アプリケーションが少量のデータのみを交換する場合、TCP接続の確立フェーズは、少なくともその情報(および往復時間の2倍)を送信します。
udpechoclienttest.java
public static void main(string [] args)throws ioexception {inetAddress serverAddress = inetAddress.getByname(args [0]); byte [] bytestosend = args [1] .getBytes(); datagramsocket socket = new DatagramSocket(); socket.setsotimeout(3000); datagrampacket sendpacket = new datagrampacket(bytestosend、bytestosend.length、serverAddress、7); datagrampacket receivepacket = new datagrampacket(new byte [bytestosend.length]、bytestosend.length); //パケットが失われる可能性があるため、int tries = 0を試してみる必要があります。 boolean receiveResponse = false; do {socket.send(sendpacket); try {socket.receive(receivepacket); if(!receivepacket.getAddress()。equals(serverAddress))new ioException( "receive from unknown source"); receiveResponse = true; } catch(ioException e){tries ++; System.out.println( "Timeout、再試行してください"); }} while(!receeceResponse && tries <5); if(ReceiveResponse)System.out.println( "receece:" + new String(receivePacket.getData()); else system.out.println( "応答なし"); socket.close(); } udpechoservertest.java
Private Static Final int echomax = 255; public static void main(string [] args)throws ioexception {datagramsocket socket = new datagramsocket(7); datagrampacketパケット= new datagrampacket(new byte [echomax]、echomax); while(true){socket.receive(packet); system.out.println( "" + packet.getAddress())のクライアントの処理socket.send(packet); packet.setlength(echomax); }}この例を以前のTCPインスタンスと比較すると、次の違いがあります。
A.DatagramSocketは、UDPが接続を確立する必要がなく、各データパケットを別の宛先アドレスから送信または受信できるため、作成時に宛先アドレスを指定する必要はありません。
B.ブロックしてTCPのようにread()を待つと、UDPプロトコルは単にIPプロトコルを拡張し、UDPパケットが失われる可能性があるため、そこでは永遠にブロックされる可能性があります。したがって、待機をブロックするためのタイムアウト時間を設定する必要があります。
c.udpプロトコルはメッセージの境界情報を保持し、各受信()コールはsend()メソッドコールで送信されたデータのみを1回受信できます。
D. UDPパケットが送信できる最大データは65507バイトです。余分なバイトは自動的に破棄され、受信プログラムの迅速なものはありません。したがって、キャッシュアレイを約65,000バイトに設定することは安全です。
E.受信()メソッドが同じDataGrampacketインスタンスで繰り返し呼び出された場合、メッセージの内部長さは、各呼び出しの前にキャッシュの実際の長さに明示的にリセットする必要があります。