基於tcp和udp的socket實現

 

 本文介紹如何用Java實現Socket編程。首先介紹Java針對Socket編程提供的類,以及它們之間的關係。而後分別針對TCP和UDP兩種傳輸層協議實現Socket編程。html

1 Java中的Socket編程接口介紹

Java爲Socket編程封裝了幾個重要的類。前端

1.1 Socket類

Socket類實現了一個客戶端socket,做爲兩臺機器通訊的終端,默認採用的傳輸層協議爲TCP,是一個可靠傳輸的協議。Socket類除了構造函數返回一個socket外,還提供了connect, getOutputStream, getInputStream和close方法。connect方法用於請求一個socket鏈接,getOutputStream用於得到寫socket的輸出流,getInputStream用於得到讀socket的輸入流,close方法用於關閉一個流。java

1.2 DatagramSocket類

DatagramSocket類實現了一個發送和接收數據報的socket,傳輸層協議使用UDP,不能保證數據報的可靠傳輸。DataGramSocket主要有send, receive和close三個方法。send用於發送一個數據報,Java提供了DatagramPacket對象用來表達一個數據報。receive用於接收一個數據報,調用該方法後,一直阻塞接收到直到數據報或者超時。close是關閉一個socket。python

1.3 ServerSocket類

ServerSocket類實現了一個服務器socket,一個服務器socket等待客戶端網絡請求,而後基於這些請求執行操做,並返回給請求者一個結果。ServerSocket提供了bind、accept和close三個方法。bind方法爲ServerSocket綁定一個IP地址和端口,並開始監聽該端口。accept方法爲ServerSocket接受請求並返回一個Socket對象,accept方法調用後,將一直阻塞直到有請求到達。close方法關閉一個ServerSocket對象。程序員

1.4 SocketAddress

SocketAddress提供了一個socket地址,不關心傳輸層協議。這是一個虛類,由子類來具體實現功能、綁定傳輸協議。它提供了一個不可變的對象,被socket用來綁定、鏈接或者返回數值。面試

1.5 InetSocketAddress

InetSocketAddress實現了IP地址的SocketAddress,也就是有IP地址和端口號表達Socket地址。若是不制定具體的IP地址和端口號,那麼IP地址默認爲本機地址,端口號隨機選擇一個。編程

1.6. DatagramPacket

DatagramSocket是面向數據報socket通訊的一個可選通道。數據報通道不是對網絡數據報socket通訊的徹底抽象。socket通訊的控制由DatagramSocket對象實現。DatagramPacket須要與DatagramSocket配合使用才能完成基於數據報的socket通訊。跨域

 2. 基於TCP的Socket編程

上面描述了Java對Socket編程提供的接口,本節介紹如何實現一個基於TCP鏈接的Socket通訊。服務器

下面例子是Server端等待從Client端接收一條消息,而後再給客戶端發送一個消息。微信

服務器端首先實例化ServerSocket對象,而後爲其綁定一個本機地址,並開始監聽。一直阻塞狀態下等待客戶端請求,當得到客戶端鏈接請求後,返回一個socket對象。而後用這個socket接收一條消息,併發送一條消息。代碼以下:

複製代碼

package server.socket.java;

import java.io.IOException;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketAddress;

public class SocketTcp {
    static private String TAG = "SocketTcp: ";
    
    public static void main(String[] args){
        try {
            ServerSocket server = new ServerSocket();
            SocketAddress address = new InetSocketAddress(InetAddress.getLocalHost(), 10001);
            server.bind(address);
            System.out.println("==waiting for being connected...");
            Socket client = server.accept();
            System.out.println("==connected with " + 
                    client.getRemoteSocketAddress() );
            
            PrintWriter socketOut = new PrintWriter(client.getOutputStream());
            
            System.out.println("==waiting message from client...");
            byte buf[] = new byte[1024];
            if ( client.getInputStream().read(buf) > 0 ) {
                System.out.println("Receive Message: " + new String(buf));
            }
            
            System.out.println("==sending message to client...");
            String sendStr = "This is the message for client.";
            socketOut.write(sendStr);
            socketOut.flush();
            
            socketOut.close();
            client.close();
            server.close();
        } catch (IOException e) {
            System.out.println(TAG + e.getMessage());
            e.printStackTrace();
        }
    }
}

複製代碼

 

 客戶端首先實例化一個socket對象,用這個對象鏈接服務器端。鏈接成功後,發送一條消息,而後等待接收一條消息。代碼以下:

複製代碼

package client.socket.java;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketAddress;

public class SocketTcp {
    static private String TAG = "SocketTcp: ";
    
    public static void main(String[] args){
        try {
            final Socket socket = new Socket();
            SocketAddress address = new InetSocketAddress(InetAddress.getLocalHost(), 10001);
            System.out.println("==connecting to server ...");
            socket.connect(address);
            
            PrintWriter socketOut = new PrintWriter(socket.getOutputStream());
            BufferedReader socketIn = new BufferedReader(
                    new InputStreamReader(socket.getInputStream()) );
            
            String sendStr = "This is the message for server.";
            System.out.println("==sending message to server ...");
            socketOut.write(sendStr);
            socketOut.flush();
            System.out.println("==waiting message from server ...");
            String receiveStr = socketIn.readLine();
            System.out.println("Receive Message: " + receiveStr);
            
            socketOut.close();
            socketIn.close();
            socket.close();
        } catch (IOException e) {
            System.out.println(TAG + e.getMessage());
            e.printStackTrace();
        } finally {
            
        }
    }
}

複製代碼

 服務器端運行結果: 

==waiting for being connected...
==connected with /172.26.176.69:53912
==waiting message from client...
Receive Message: This is the message for server.

 客戶端運行結果: 

==connecting to server ...
==sending message to server ...
==waiting message from server ...
Receive Message: This is the message for client.

 3 基於UDP的Socket編程示例

 基於UDP的Socket編程與基於TCP的socket編程稍有不一樣,socket server和client都用DatagramSocket實現。

 下面例子是Server端等待從Client端接收一條消息,而後再給客戶端發送一個消息。

 服務器端首先實例化DatagramSocket對象,而後爲其綁定一個本機地址,並開始監聽。一直阻塞狀態下等待從客戶端接收數據報。而後從數據報中獲取數據報的源地址,而後用這個源地址做爲目的地址打包一個數據報,而後發送出去。代碼以下:

複製代碼

package server.socket.java;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.net.SocketException;
import java.net.UnknownHostException;

public class SocketUdp {
    final private static String TAG = "SocketUdp: ";
    
    public static void main(String args[]) {
        DatagramSocket socket = null;
        DatagramPacket datapacket = null;
        InetSocketAddress address = null;
        
        try {
            address = new InetSocketAddress(InetAddress.getLocalHost(), 7778);
            socket = new DatagramSocket(address);
            // socket.bind(address);
            
            byte buf[] = new byte[1024];
            datapacket = new DatagramPacket(buf, buf.length);
            System.out.println("==block for receive messages...");
            socket.receive(datapacket);
            buf = datapacket.getData();
            InetAddress addr = datapacket.getAddress();
            int port = datapacket.getPort();
            System.out.println("Message Content: " + new String(buf) );
            System.out.println("Receive From " + addr + ":" + port);
            
            SocketAddress toAddress = datapacket.getSocketAddress();
            String sendStr = "I'm Server, this is the message for client.";
            buf = sendStr.getBytes();
            datapacket = new DatagramPacket(buf, buf.length);
            datapacket.setSocketAddress(toAddress);
            socket.send(datapacket);
            System.out.println("==message sended");
            
        } catch (UnknownHostException e) {
            System.out.println(TAG + e.getMessage());
            e.printStackTrace();
        } catch (SocketException e) {
            System.out.println(TAG + e.getMessage());
            e.printStackTrace();
        } catch (IOException e) {
            System.out.println(TAG + e.getMessage());
            e.printStackTrace();
        }
    }

}

複製代碼

  客戶端首先實例化一個DatagramSocket對象。利用服務器地址和端口號做爲目的地址打包一個數據報,併發送。而後等待從服務器回覆的數據報。代碼以下: 

複製代碼

package client.socket.java;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.SocketException;
import java.net.UnknownHostException;

public class SocketUdp {
    final private static String TAG = "SocketUdp: ";
    
    public static void main(String args[]) {
        try {
            DatagramSocket getSocket = new DatagramSocket();
            DatagramPacket datapacket = null;
            InetSocketAddress toAddress = new InetSocketAddress(InetAddress.getLocalHost(), 7778);
            
            String sendStr = "I'm client, this is the message for server.";
            byte buf[] = sendStr.getBytes();
            datapacket = new DatagramPacket(buf, buf.length);
            datapacket.setSocketAddress(toAddress);
            getSocket.send(datapacket);
            System.out.println("==message sended");
            
            System.out.println("==block for receive messages...");
            getSocket.receive(datapacket);
            buf = datapacket.getData();
            System.out.println("Message Content: " + new String(buf));
        } catch (SocketException e) {
            System.out.println(TAG + e.getMessage());
            e.printStackTrace();
        } catch (UnknownHostException e) {
            System.out.println(TAG + e.getMessage());
            e.printStackTrace();
        } catch (IOException e) {
            System.out.println(TAG + e.getMessage());
            e.printStackTrace();
        }
        
    }
}

複製代碼

 服務器端運行結果:

==block for receive messages...
Message Content: I'm client, this is the message for server.

 客戶端運行結果:

==message sended
==block for receive messages...
Message Content: I'm Server, this is the message for client.

分類: 網絡編程,Java學習筆記

好文要頂 關注我 收藏該文  

洪雁君
關注 - 7
粉絲 - 3

+加關注

0

0

« 上一篇:傳輸層中的TCP和UDP淺析
» 下一篇:長鏈接與短鏈接

posted on 2013-09-02 00:56 洪雁君 閱讀(4109) 評論(0) 編輯 收藏

 

刷新評論刷新頁面返回頂部

註冊用戶登陸後才能發表評論,請 登陸 或 註冊訪問網站首頁。

【推薦】50萬行VC++源碼: 大型組態工控、電力仿真CAD與GIS源碼庫
【活動】阿里雲雙11活動開始預熱 雲服務器限時2折起
【調查】有獎調研即刻參與,你居然是醬紫程序猿!
【推薦】Vue.js 2.x 快速入門,大量高效實戰示例

葡萄城

最新IT新聞:
· 《周鴻禕自傳》書摘:首談私有化,我從沒想過退出
· 一個老外的自述:「在中國手機就是個人生命」
· PayPal CEO:將來5年內 金融科技變化將遠超過去30年
· 快遞員迴應"月薪過萬":送1件提成1元 雙11可掙萬元
· 微軟收購動態圖片應用程序Swng 團隊加入Skype部門
» 更多新聞...

阿里雲雙11

最新知識庫文章:

· 關於編程,你的練習是否是有效的?
· 改善程序員生活質量的 3+10 習慣
· NASA的10條代碼編寫原則
· 爲何你參加了那麼多培訓,卻依然表現平平?
· 寫給初學前端工程師的一封信

» 更多知識庫文章...

Powered by: 
博客園 
Copyright © 洪雁君

< 2017年11月 >
29 30 31 1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 1 2
3 4 5 6 7 8 9

導航

統計

  • 隨筆 - 27
  • 文章 - 1
  • 評論 - 1
  • 引用 - 0

公告

暱稱:洪雁君
園齡:7年6個月
粉絲:3
關注:7

+加關注

搜索

 

 

經常使用連接

個人標籤

隨筆分類

隨筆檔案

相冊

最新評論

閱讀排行榜

推薦排行榜

相關文章
相關標籤/搜索