Java Socket編程(二)Socket基礎__演算法

來源:互聯網
上載者:User

二、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 tryingint 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()));elseSystem.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()方法,每次調用前都必須顯式 地將訊息的內部長度重設為緩衝區的實際長度。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.