国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > Java > 正文

Java的Socket網絡編程基礎知識入門教程

2019-11-26 14:40:11
字體:
來源:轉載
供稿:網友

一、TCP/IP簡介

TCP/IP協議族是互聯網使用的協議,也可以用在獨立的專用網絡中。
TCP/IP協議族包括了IP協議、TCP協議和UDP協議。

IP協議使用IP地址來分發報文,但它是盡力而為的服務,報文可能丟失、亂序或者
重復發送。TCP和UDP協議在IP協議基礎上增加了端口號,從而在兩臺主機的應用
程序間建立起透明的連接。

不同的是,TCP協議會對IP層的錯誤進行修復,它通過握手消息在主機間建立連接,
之后通過在消息中加入序列號來恢復消息中的錯誤。而UDP只是簡單地擴展了IP協議,
使它能夠在應用程序之間工作,而不是主機之間。

關于IP地址,一臺主機可以有多個網絡接口,而一個接口又可以有多個地址。
有些IP地址是有特殊用途的:

A.回環地址:127.0.0.1,總是被分配給一個回環接口,主要用于測試。

B.私有地址:以10、192.168、172.(16-31)開頭,用于私有網絡。NAT設備轉發報文
時,將一個接口中報文的私有地址端口對映射成另一個接口中的公有地址端口對。這
就使一小組主機能夠共享一個IP地址對。

C.多播地址:第一個數字在224~239之間。

二、Socket基礎

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實例程序

要注意一點,雖然在Client端只用了一個write()方法發送字符串,服務器端也可能從
多個塊中接受該信息。即使回饋字符串在服務器返回時存于一個塊中,也可能被TCP
協議分割成多個部分。

TCPEchoClientTest.java

public static void main(String[] args) throws IOException {    String server = args[0];   byte[] data = args[1].getBytes();   int port = 7;      Socket socket = new Socket(server, port);   System.out.println("Connected to 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,          data.length - totalBytesRcvd)) == -1)       throw new SocketException("Connection closed");     totalBytesRcvd += bytesRcvd;   }      System.out.println("Received: " + 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("Handling client " +         " from remote " + socket.getRemoteSocketAddress() +          " at local " + socket.getLocalSocketAddress());          InputStream in = socket.getInputStream();     OutputStream out = socket.getOutputStream();          while ((recvMsgSize = in.read(receiveBuf)) != -1) {       out.write(receiveBuf, 0, recvMsgSize);     }     socket.close();   }    } 

注意new Socket時指定的是遠端服務器監聽的端口號而沒有指定本地端口,因此將
采用默認地址和可用的端口號。在我的機器上Client端口是4593,連接到服務器的
端口7。


3.UDP實例程序

為什么使用UDP協議?如果應用程序只交換少量的數據,TCP連接的建立階段就至少
要傳輸其兩倍的信息量(還有兩倍的往返時間)。

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);      // Packets may be lost, so we have to keep trying   int tries = 0;   boolean receivedResponse = false;   do {     socket.send(sendPacket);     try {       socket.receive(receivePacket);       if (!receivePacket.getAddress().equals(serverAddress))         throw new IOException("Receive from unknown source");       receivedResponse = true;     }      catch (IOException e) {       tries++;       System.out.println("Timeout, try again");     }   } while (!receivedResponse && tries < 5);      if (receivedResponse)     System.out.println("Received: " + new String(receivePacket.getData()));   else     System.out.println("No response");      socket.close(); } 

UDPEchoServerTest.java

private static final int ECHOMAX = 255;   public static void main(String[] args) throws IOException {    DatagramSocket socket = new DatagramSocket(7);   DatagramPacket packet = new DatagramPacket(new byte[ECHOMAX], ECHOMAX);      while (true) {     socket.receive(packet);     System.out.println("Handling client at " + packet.getAddress());          socket.send(packet);     packet.setLength(ECHOMAX);   }    } 

通過這個例子與之前TCP的實例進行比較,有如下區別:

A.DatagramSocket在創建時不需要指定目的地址,因為UDP不需要建立連接,每個
數據報文都可以發送或接收于不同的目的地址。

B.如果像TCP一樣在read()上阻塞等待,將可能永遠阻塞在那里,因為UDP協議只是
簡單地擴展了IP協議,UDP報文可能丟失掉。所以一定要設置阻塞等待的超時時間。

C.UDP協議保留了消息的邊界信息,每次receive()調用最多只能接收一次send()方法
調用所發送的數據。

D.一個UDP報文DatagramPacket能傳輸的最大數據是65507字節,超出部分的字節將
自動被丟棄,而且對接收程序也沒有任何的提示。因此緩存數組可以設置成65000字節
左右是安全的。

E.如果反復使用同一個DatagramPacket實例調用receive()方法,每次調用前都必須顯式
地將消息的內部長度重置為緩存區的實際長度。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 永城市| 山丹县| 黄冈市| 固原市| 忻城县| 宿松县| 收藏| 南通市| 葫芦岛市| 胶南市| 宣威市| 凌云县| 峨眉山市| 南漳县| 阳东县| 茌平县| 桐庐县| 陆丰市| 大悟县| 勐海县| 淮北市| 营山县| 德化县| 乌拉特中旗| 奈曼旗| 榆中县| 太原市| 开平市| 舟曲县| 常山县| 介休市| 山西省| 万盛区| 彰化市| 蛟河市| 商河县| 科尔| 林州市| 宕昌县| 从化市| 台东县|