Socket和ServerSocket學習筆記
對於即時類應用或者即時類的遊戲,HTTP協議很多時候無法滿足於我們的需求。這會,Socket對於我們來說就非常實用了。下面是本次學習的筆記。主要分異常型別、互動原理、Socket、ServerSocket、多執行緒這幾個方面闡述。
異常型別 在瞭解Socket的內容之前,先要了解一下涉及到的一些異常型別。以下四種類型都是繼承於IOException,所以很多之後直接彈出IOException即可。 UnkownHostException: 主機名字或IP錯誤 ConnectException: 伺服器拒絕連線、伺服器沒有啟動、(超出佇列數,拒絕連線) SocketTimeoutException: 連線超時 BindException: Socket物件無法與制定的本地IP地址或埠繫結 互動過程在客戶/伺服器通訊模式中,伺服器端需要建立監聽特定埠的ServerSocket,ServerSocket負責接收客戶連線請求。本章首先介紹ServerSocket類的各個構造方法,以及成員方法的用法,接著介紹伺服器如何用多執行緒來處理與多個客戶的通訊任務。
本章提供執行緒池的一種實現方式。執行緒池包括一個工作佇列和若干工作執行緒。伺服器程式向工作佇列中加入與客戶通訊的任務,工作執行緒不斷從工作佇列中取出任務並執行它。本章還介紹了Java.util.concurrent包中的執行緒池類的用法,在伺服器程式中可以直接使用它們。
3.1 構造ServerSocket
ServerSocket的構造方法有以下幾種過載形式:
◆ServerSocket()throws IOException
◆ServerSocket(int port) throws IOException
◆ServerSocket(int port, int backlog) throws IOException
◆ServerSocket(int port, int backlog, InetAddress bindAddr) throws IOException
在以上構造方法中,引數port指定伺服器要繫結的埠(伺服器要監聽的埠),引數backlog指定客戶連線請求佇列的長度,引數bindAddr指定伺服器要繫結的IP地址。
3.1.1 繫結埠
除了第一個不帶引數的構造方法以外,其他構造方法都會使伺服器與特定埠繫結,該埠由引數port指定。例如,以下程式碼建立了一個與80埠繫結的伺服器:
- ServerSocket serverSocket=new ServerSocket(80);
◆在某些作業系統中,如果沒有以超級使用者的身份來執行伺服器程式,那麼作業系統不允許伺服器繫結到1~1023之間的埠。
如果把引數port設為0,表示由作業系統來為伺服器分配一個任意可用的埠。由作業系統分配的埠也稱為匿名埠。對於多數伺服器,會使用明確的埠,而不會使用匿名埠,因為客戶程式需要事先知道伺服器的埠,才能方便地訪問伺服器。在某些場合,匿名埠有著特殊的用途,本章3.4節會對此作介紹。
3.1.2 設定客戶連線請求佇列的長度
當伺服器程序執行時,可能會同時監聽到多個客戶的連線請求。例如,每當一個客戶程序執行以下程式碼:
- Socket socket=new Socket(www.javathinker.org,80);
就意味著在遠端www.javathinker.org主機的80埠上,監聽到了一個客戶的連線請求。管理客戶連線請求的任務是由作業系統來完成的。作業系統把這些連線請求儲存在一個先進先出的佇列中。許多作業系統限定了佇列的最大長度,一般為50。當佇列中的連線請求達到了佇列的最大容量時,伺服器程序所在的主機會拒絕新的連線請求。只有當伺服器程序通過ServerSocket的accept()方法從佇列中取出連線請求,使佇列騰出空位時,佇列才能繼續加入新的連線請求。
對於客戶程序,如果它發出的連線請求被加入到伺服器的佇列中,就意味著客戶與伺服器的連線建立成功,客戶程序從Socket構造方法中正常返回。如果客戶程序發出的連線請求被伺服器拒絕,Socket構造方法就會丟擲ConnectionException。
ServerSocket構造方法的backlog引數用來顯式設定連線請求佇列的長度,它將覆蓋作業系統限定的佇列的最大長度。值得注意的是,在以下幾種情況中,仍然會採用作業系統限定的佇列的最大長度:
◆backlog引數的值大於作業系統限定的佇列的最大長度;
◆backlog引數的值小於或等於0;
◆在ServerSocket構造方法中沒有設定backlog引數。
以下例程3-1的Client.java和例程3-2的Server.java用來演示伺服器的連線請求佇列的特性。
例程3-1 Client.java
- import java.net.*;
- publicclass Client {
- publicstaticvoid main(String args[])throws Exception{
- finalint length=100;
- String host="localhost";
- int port=8000;
- Socket[] sockets=new Socket[length];
- for(int i=0;i<length;i++){ // 試圖建立100次連線
- sockets[i]=new Socket(host, port);
- System.out.println("第"+(i+1)+"次連線成功");
- }
- Thread.sleep(3000);
- for(int i=0;i<length;i++){
- sockets[i].close(); //斷開連線
- }
- }
- }
- import java.io.*;
- import java.net.*;
- publicclass Server {
- privateint port=8000;
- private ServerSocket serverSocket;
- public Server() throws IOException {
- serverSocket = new ServerSocket(port,3); //連線請求佇列的長度為3
- System.out.println("伺服器啟動");
- }
- publicvoid service() {
- while (true) {
- Socket socket=null;
- try {
- socket = serverSocket.accept(); //從連線請求佇列中取出一個連線
- System.out.println("New connection accepted " +
- socket.getInetAddress() + ":" +socket.getPort());
- }catch (IOException e) {
- e.printStackTrace();
- }finally {
- try{
- if(socket!=null)socket.close();
- }catch (IOException e) {e.printStackTrace();}
- }
- }
- }
- publicstaticvoid main(String args[])throws Exception {
- Server server=new Server();
- Thread.sleep(60000*10); //睡眠10分鐘
- //server.service();
- }
- }
例程3-2 Server.java
Client試圖與Server進行100次連線。在Server類中,把連線請求佇列的長度設為3。這意味著當佇列中有了3個連線請求時,如果Client再請求連線,就會被Server拒絕。下面按照以下步驟執行Server和Client程式。
(1)把Server類的main()方法中的“server.service();”這行程式程式碼註釋掉。這使得伺服器與8000埠繫結後,永遠不會執行serverSocket.accept()方法。這意味著佇列中的連線請求永遠不會被取出。先執行Server程式,然後再執行Client程式,Client程式的列印結果如下:
- 第1次連線成功
- 第2次連線成功
- 第3次連線成功
- Exception in thread "main" java.net.ConnectException: Connection refused: connect
- at java.net.PlainSocketImpl.socketConnect(Native Method)
- at java.net.PlainSocketImpl.doConnect(Unknown Source)
- at java.net.PlainSocketImpl.connectToAddress(Unknown Source)
- at java.net.PlainSocketImpl.connect(Unknown Source)
- at java.net.SocksSocketImpl.connect(Unknown Source)
- at java.net.Socket.connect(Unknown Source)
- at java.net.Socket.connect(Unknown Source)
- at java.net.Socket.(Unknown Source)
- at java.net.Socket.(Unknown Source)
- at Client.main(Client.java:10)
- publicstaticvoid main(String args[])throws Exception {
- Server server=new Server();
- //Thread.sleep(60000*10); //睡眠10分鐘
- server.service();
- }
作了以上修改,伺服器與8 000埠繫結後,就會在一個while迴圈中不斷執行serverSocket.accept()方法,該方法從佇列中取出連線請求,使得佇列能及時騰出空位,以容納新的連線請求。先執行Server程式,然後再執行Client程式,Client程式的列印結果如下:
- 第1次連線成功
- 第2次連線成功
- 第3次連線成功
- …
- 第100次連線成功
從以上列印結果可以看出,此時Client能順利與Server建立100次連線。
3.1.3 設定繫結的IP地址
如果主機只有一個IP地址,那麼預設情況下,伺服器程式就與該IP地址繫結。ServerSocket的第4個構造方法ServerSocket(int port, int backlog, InetAddress bindAddr)有一個bindAddr引數,它顯式指定伺服器要繫結的IP地址,該構造方法適用於具有多個IP地址的主機。假定一個主機有兩個網絡卡,一個網絡卡用於連線到Internet, IP地址為222.67.5.94,還有一個網絡卡用於連線到本地區域網,IP地址為192.168.3.4。如果伺服器僅僅被本地區域網中的客戶訪問,那麼可以按如下方式建立ServerSocket:
相關推薦
Socket和ServerSocket學習筆記
對於即時類應用或者即時類的遊戲,HTTP協議很多時候無法滿足於我們的需求。這會,Socket對於我們來說就非常實用了。下面是本次學習的筆記。主要分異常型別、互動原理、Socket、ServerSocket、多執行緒這幾個方面闡述。 異常型別 在瞭解Socket的內容之前,先要了解一下涉及到的一
[Java]Socket和ServerSocket學習筆記
對於即時類應用或者即時類的遊戲,HTTP協議很多時候無法滿足於我們的需求。這會,Socket對於我們來說就非常實用了。下面是本次學習的筆記。主要分異常型別、互動原理、Socket、ServerSocket、多執行緒這幾個方面闡述。 異常型別 在瞭解Socket的內容之前,先要了解一下涉及到的一些異常型別
[Java]Socket和ServerSocket學習
對於即時類應用或者即時類的遊戲,HTTP協議很多時候無法滿足於我們的需求。這會,Socket對於我們來說就非常實用了。 下面是本次學習的筆記。主要分異常型別、互動原理、Socket、ServerSocket、多執行緒這幾個方面闡述。 異常型別 在瞭解Socket的內容
安卓和 java 學習筆記
點擊 進行 sha ring text div -a 變量 tco 1、訪問權限為 private 的成員變量或方法,需要執行setAccessible() 方法,並將入口參數設置為 true; 否則不允許訪問。 2、為了保證線程的安全,可以使用同步塊 synchron
流暢的python和cookbook學習筆記(一)
構造函數 推導 笛卡爾 expr 列表推導 叠代 建立 笛卡兒 imp 1.數據結構 1.1 內置序列類型 四種序列類型: 1.容器序列:list、tuple和collections.deque 2.扁平序列:str、bytes、bytearray、memory
流暢的python和cookbook學習筆記(五)
pytho col () 學習 util 學習筆記 取出 minute python 1.隨機選擇 python中生成隨機數使用random模塊。 1.從序列中隨機挑選元素,使用random.choice() >>> import random
流暢的python和cookbook學習筆記(八)
不可變 pri 列表 改變 如果 book 影響 color print 1.函數的默認參數必須不可變 如果函數的默認參數為可變的對象,那麽默認參數在函數外被修改也會影響到函數本身的。 >>> def spam(a, b=None): # b要為不
神經網絡和深度學習 筆記
ack 參數 一個 bsp 感知機 信號 叠代 前饋型神經網絡 pro 人工神經網絡(ann) 模擬的是 生物神經網絡(bnn) ann 一般也叫 前饋型神經網絡 : 各神經元只接受前一級輸入,並輸出到下一級,無反饋 應該也有反饋型神經網絡?? ann一般使用b
python——元組和字典學習筆記
deepcopy 例子 [] items 是個 rev put 次數 style 1.count返回值的次數 list=[2,2,2,3,3,3,3,4,4,4] a={} for i in list: if list.count(i)>1:
this和super的區別和應用 學習筆記
pri xtend In ID AR super string print pub A:this和super都代表什麽 this:代表當前對象的引用,誰來調用我,我就代表誰 super:代表當前對象父類的引用 B:this和super的使用區別 a:調用成員變量 t
JSP和Servlet學習筆記1 - 訪問配置
技術分享 exception print pack ping 分享 tdi 1.0 nds 1. 訪問WebContent目錄下的JSP文件 在WebContent中新建一個 test.jsp 文件 <%@ page language="java" co
工廠方法模式的概述和使用學習筆記
每次 extend ride xtend tor 自己 pre ide 抽象類 A:工廠方法模式概述 工廠方法模式中抽象工廠類負責定義創建對象的接口,具體對象的創建工作由繼承抽象工廠的具體類實現。 B:優點 客戶端不需要在負責對象的創建,從而明確了各個類的職責,如果有
線程池的概述和使用學習筆記
pre 應該 code call adp 關閉 產生 提高 single A:線程池概述程序啟動一個新線程成本是比較高的,因為它涉及到要與操作系統進行交互。而使用線程池可以很好的提高性能,尤其是當程序中要創建大量生存期很短的線程時,更應該考慮使用線程池。線程池裏的每一個線程
網路程式設計(InetAddress類、Socket和ServerSocket、實現客戶端和伺服器之間的雙向通訊)
網路程式設計的底層是IO,通過IO將一臺計算機中的資料傳送到另一臺計算機中。傳送的時候,要知道接受方的地址,該地址即為IP地址。知道IP地址後即可進行傳送。A向B發訊息,訊息是發過去了,但是B要怎樣接受呢?因此定義了埠,B監聽了A所使用的埠。A發的訊息中含有埠號,當B接受到訊息時,知道了埠號
【學會Matlab走遍天下】如何畫正弦餘弦曲線和(學習筆記)
常用命令: clc %清屏 clear + 變數 %將變數擦除 註釋符:% 矩陣建立 邏輯語法 sum=0;i=1; while(i<=100) sum=sum+i;i=i+1; sum
AJAX和JSON學習筆記
1.關係對映 - 多對多 物件名 = db.Table( '關聯表名', db.Column('id',db.Integer,primary_key=True), db.Column('外來鍵列名',db.TYPE,db.ForeignKey('主表.主鍵')), db.Column('外來鍵列名',db.T
html和css學習筆記(二)
1表格 1.1table tr td 1.2表格屬性 width border align="center" cellspacing 單元格邊框和單元格邊框之間的距離 cellpadding 單元格內容與單元格邊框之間的距離 *三參為0 border cellspaci
C++類和物件學習筆記(3)
1.初始化列表 a.建構函式體賦值 在建立物件時,編譯器可以通過呼叫建構函式,給物件中各個成員變數一個合適的初始值。但是雖然建構函式呼叫之後,物件中已經有了一個初始值,但是不能將其稱作為類物件成員的
AlexNet和VGG學習筆記
AlexNet 2012年,Alex Krizhevsky(Hinton的學生)提出了AlexNet,它可以看做是LeNet的一個更深更寬版本。 這就是Gradient-Based Learning Applied to Document Recognition論文裡
x i l i n x -selectio和clocking學習筆記
最近做高速視訊影象採集相關的工作,需要對FPGA的selectio以及clocking資源有足夠的瞭解,於是把xilinx的ug381,ug382, xapp1064文件閱讀了一遍, 結合實際除錯中遇到的問題,總結了如下要點。 1, selectio sp