Java Socket網絡編程Server端詳解

Socket通訊:分爲客戶端和服務端的socket代碼。java

Java SDK提供一些相對簡單的Api來完成.對於Java而言.這些Api存在與java.net 這個包裏面.所以只要導入這個包就能夠開始網絡編程了。編程

  網絡編程的基本模型就是客戶機到服務器模型。簡單的說就是兩個進程之間相互通信,而後其中一個必須提供一個固定的位置,而另外一個則只須要知道這個固定的位置。並去創建二者之間的聯繫,而後完成數據的通信就能夠了。這裏提供固定位置的一般稱爲服務器,而創建聯繫的一般叫作客戶端。瞭解這個簡單的模型,就能夠網絡編程了。 Java對這個模型的支持有不少種Api。而這裏我只想介紹有關Socket的編程接口,對於Java而言已經簡化了Socket的編程接口。數組

建立服務器端實例有四種構造函數能夠實現(Java提供了ServerSocket來對其進行支持):  服務器

  

首先,咱們來討論有關提供固定位置的服務方是如何創建的。事實上當你建立該類的一個實力對象並提供一個端口資源你就創建了一個固定位置可讓其餘計算機來訪問你。網絡

 

ServerSocket server=new ServerSocket(int port);  //port - 端口號;或者爲 0,表示使用任何空閒端口。

 

 

 

這裏稍微要注意的是端口的分配必須是惟一的。由於端口是爲了惟一標識每臺計算機惟一服務的,另外端口號是從0~65535之間的,前1024個端口已經被Tcp/Ip 做爲保留端口,所以你所分配的端口只能是1024個以後的。socket

建立綁定到特定端口的服務器套接字。端口 0 在全部空閒端口上建立套接字。輸入鏈接指示(對鏈接的請求)的最大隊列長度被設置爲 50。若是隊列滿時收到鏈接指示,則拒絕該鏈接。ide

 

其次,建立非綁定服務器。函數

ServerSocket server=new ServerSocket();  //建立非綁定服務器套接字

  

第三,建立指定端口,最大鏈接數的服務器。this

ServerSocket server=new ServerSocket(int port,int backlog); //port - 指定的端口;或者爲 0,表示使用任何空閒端口。backlog - 隊列的最大長度。

利用指定的 backlog 建立服務器套接字並將其綁定到指定的本地端口號。端口號 0 在全部空閒端口上建立套接字。輸入鏈接指示(對鏈接的請求)的最大隊列長度被設置爲 backlog 參數。若是隊列滿時收到鏈接指示,則拒絕該鏈接。backlog 參數必須是大於 0 的正值。若是傳遞的值等於或小於 0,則假定爲默認值。spa

  

第四,建立指定端口,最大鏈接數,指定IP的服務器。

ServerSocket server=new ServerSocket(int port,int backlog,InetAddress bindAddr);//port - 本地 TCP 端口;backlog - 偵聽 
//backlog;bindAddr - 要將服務器綁定到的 InetAddress 

 

使用指定的端口、偵聽 backlog 和要綁定到的本地 IP 地址建立服務器。bindAddr 參數能夠在 ServerSocket 的多穴主機 (multi-homed host) 上使用,ServerSocket 僅接受對其地址之一的鏈接請求。若是 bindAddr 爲 null,則默認接受任何/全部本地地址上的鏈接。端口必須在 0 到 65535 之間(包括二者)。

服務器端實例建立完成之後,就可使用線程池來處理客戶端發來的請求數據了。

ExecutorService pool = Executors.newFixedThreadPool(int poolSize); //poolSize 固定線程池大小

 

下面給出了一個網絡服務的簡單結構,這裏線程池中的線程做爲傳入的請求。它使用了預先配置的 Executors.newFixedThreadPool(int) 工廠方法:

ServerThread.java

public class ServerThread extends Thread //此處亦能夠實現Runnable接口
{
    private InputStream ins = null;
    private PrintWriter out = null;

    public ServerThread(Socket socket)
    {
        try
        {
            ins = socket.getInputStream();
            out = new PrintWriter(socket.getOutputStream(), true);
            socket.setSoTimeout(1000);
        }
        catch (IOException e)
        {
            e.printStackTrace();
            interrupt(); // 若是發生異常 則終止線程
        }
    }

    public void run()
    {
        try
        {
            // 初始化構造函數之後會執行到這裏
            //從輸入流中取出數據並轉換成字符串格式
            //處理客戶端請求過來的相應數據,並作處理
            String instr = "";
            int temp = -1;
            List<Byte> byteList = new ArrayList<Byte>();
            while(true)
            {
                try 
                {
                    temp = ins.read();
                    if(temp != -1)
                    {
                        byteList.add(new Byte((byte)temp));
                    }
                    else
                    {
                        break;
                    }
                }
                catch (IOException e) 
                {
                    break;
                }
            }
            
            byte[] bytes = new byte[byteList.size()];
            for(int i=0;i<byteList.size();i++)
            {
                bytes[i] = byteList.get(i);
            }
            
            instr = new String(bytes);//將byte數組類型轉換爲字符串
            System.out.println("the content of recivedMessage is:" + instr); // 這裏用日誌文件記錄下收到的報文
            out.println("Request Message has been receiver!");
            out.flush();
        }
        catch(Exception ex)
        {
            ex.printStackTrace();
        }
    }
}
View Code

ServerSocketDemo.java

public class ServerSocketDemo extends Thread
{
    private  ServerSocket server = null;
    private int port = 0;
    private int poolsize = 0;
    private int maxconn = 0;
    
    public ServerSocketDemo(int port, int poolSize,int maxconn) 
    {
        System.out.println("port is:>>>>>>"+port);
        System.out.println("poolSize is:>>>>>>"+poolSize);
        System.out.println("maxconn is:>>>>>>"+maxconn);
        
        this.port = port;
        this.poolsize = poolSize;
        this.maxconn = maxconn;
    }

    public void run()
    {
        try
        {
            System.out.println("the poolsize is:>>>>" + poolsize);
            System.out.println("the port is:>>>>" + port);
            System.out.println("the maxconn is:>>>>" + maxconn);
            // 使用固定大小線程池
            ExecutorService thredpool = Executors.newFixedThreadPool(poolsize);
            server = new ServerSocket(port, maxconn);
            server.setSoTimeout(0); // 設置不會超時
            System.out.println("socket listener start!the port is:>>>>" + port
                    + " and the maxConn number is:" + maxconn
                    + "and the Thread Pool size is" + poolsize);

            while (true)
            {
                thredpool.execute(new ServerThread(server.accept()));
                System.out.println("a ServerThread has been started!");
            }
        }
        catch (Exception e)
        {
            // 這裏要用日誌文件記錄異常
            System.out.println(
                    "The serversocket listener exception occurred! the exception msg is>>>>"
                            + e.getMessage());
        }
    }
}
View Code

ServerSocketTest.java

public class ServerSocketTest {

    /**
     * @param args
     */
    public static void main(String[] args) 
    {
        // TODO Auto-generated method stub

        ServerSocketDemo ssd = new ServerSocketDemo(9997,50,100);
        ssd.start();
    }

}
View Code
相關文章
相關標籤/搜索