Java中socket接口調用
最近一個項目中接口通訊這一塊主要是調用銀聯系統的socket接口,我方是客戶端,即發送請求接收返回報文的一方。在貼代碼之前,還是要了解一下關於socket的基礎知識。
Socket的基本概念
1.建立連接
當需要建立網絡連接時,必須有一臺機器運行一個程序,隨時等候連接,而另一端的程序這對其發出連接請求。這一點同電話系統類似——必須有一方撥打電話,而另一方必須等候電話連通。
建立連接的過程為:
(1)先在服務器端生成一個ServerSocket實例對象,隨時監聽客戶端的連接請求。
(2)當客戶端需要連接服務端時,相應地要生成一個Socket實例對象,並發出連接請求,其中host參數指明該主機名,port參數指明該主機端口號。
(3)服務器端通過accept()方法接收到客戶端的請求後,開辟一個接口與之進行連接,並生成所需的I/O數據流。
(4)客戶端和服務器端的通信都是通過一對InputStream和OutputStream進行的,通信結束後,兩端分別關閉對應的Socket接口。
2.連接地址
打電話時,呼叫方必須事先知道所需撥打的號碼,而程序建立網絡連接時,也同樣需要知道地址或主機名稱。
另外,網絡連接還需要一個端口號(可以將其當作電話的分機號),連接到正確的主機之後,需要對該連接確認特定口令。
3.端口號
在TCP/IP系統中,端口號由16位二進制整數組成,即在0-65535之間。實際應用中,前1024個端口號已經預先定義為一些特定服務,因此一般不能使用,除非想同這些服務器進行連接(如Telnet,SMTP,mail,ftp等)。在兩個程序連接之前,彼此之間必須達成一致,即由客戶端負責初始化連接,而服務器隨時等候請求。只有客戶端和服務器端指定端口號一致時連接才會建立。如果系統中兩個程序所用端口號不一致,這連接無法建立。
4.網絡連接模式
在Java中,TCP/IP接口的連接是由java.net包中的類實現的。如圖表示的是Socket連接過程中客戶端和服務器端的工作原理。
每個server端都擁有一個端口號,一臺機器上如果運行多個服務,這可能對應多個端口號。通信結束後,兩端分別關閉對應的Socket接口,而不影響其他的端口。
Socket通信的基本步驟
使用Socket方式進行網絡通信的程序基本結構都是類似的,無論一個Socket通信程序的功能多麽齊全、程序多麽復雜,其基本結構都是一樣的。客戶端與服務器端進行通信的過程都包括以下四個基本步驟:
(1)在服務器端指定一個用來等待連接的端口號,在客戶端規定一個主機和端口號,從而在客戶端和服務器端創建Socket/ServerSocket實例。
(2)打開連接到Socket的輸入輸出流。
(3)利用輸入輸出流,按照一定的協議對Socket進行讀寫操作。
(4)關閉輸入輸出流和Socket
通常,程序員的主要工作時針對所要完成的功能砸器第(3)步進行編程,第(1)、(2)、(4)步對所有的通信程序來說幾乎都是一樣的。
Socket類中常用的構造函數
1:Socket(InetAddress address,int port) :該方法用於創建一個鏈接,向指定的IP地址上指定的端口的服務器端程序發送連接請求
2:Socket(InetAddress address,int port) : 同上,但該方法允許通過主機名字符串向服務器發送連接請求
Socket類中常用的方法
1:InetAddress getLocalAddress() :返回和Socket進行連接的本地的IP地址
2:int getLocalPort() :返回和Socket進行連接的本地的端口號
3:InetAddress getInetAddress():返回Socket建立了連接的服務器的IP地址
4:int getPort():返回和Socket建立了連接的服務器的端口號
5:InputStream getInputStream() :返回當前Socket的輸入流(常用)
6:OutputStream getOutStream():返回當前Socket的輸出流(常用)
7:void close():關閉當前的Socket 連接
ServerSocket中常用的構造函數
1:ServerSocket(int port) :這是構造方法用於在當前的服務器默認的IP地址上監聽一個指定的端口,即在指定的IP和端口創建一個ServerSocket對象
ServerSocket中常用的方法
1:Socket accept() :產生阻塞,監聽指定的端口,直至有客戶端發來連接請求(常用)
2:void close() :關閉當前ServerSocket
3:InetAddress getInetAddress() :返回ServerSocket監聽的本機的IP地址
4:int getLocalPort(): 返回ServerSocket監聽的,本機的IP地址上指定的端口號
5:int getSoTimeout()::void setSoTimeout(int timeout) 設置連接過程中沒有得到相應的等待期限時間(TimeOut)
6:String toString() : 以字符串的方式返回ServerSocket監聽的,本機的IP地址及其端口號
Socker通信的程序設計
終於到了貼代碼的時間了。。。。。
1.服務器端程序
public static void main(String[] args) {
// 定義ServerSocket和Socket對象
ServerSocket ss = null;
Socket sk;
// 定義發送字符串,即客戶端收到的信息
String sendString = "hello!我是服務端...";
// 定義OutputStream類
OutputStream s1out;
// 定義DataOutputStream類
DataOutputStream dos;
// 通過1314端口建立連接
try {
// 創建ServerSocket並把傳入端口號
ss = new ServerSocket(1314);
} catch (Exception e) {
e.printStackTrace();
}
// 循環運行監聽程序,以監視連接請求
while (true) {
try {
// 監聽端口請求,等待連接
sk = ss.accept();
// 得到與socket相連接的數據流對象
s1out = sk.getOutputStream();
dos = new DataOutputStream(s1out);
// 發送字符串
dos.writeUTF(sendString);
// 關閉數據流(但不是關閉Socket連接)
dos.close();
s1out.close();
sk.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
2.客戶端程序
/** * 采用socket連接向服務器發送消息,接受響應信息 註意,如果是通過不同的ip port確定調用接口 這個方法要重寫,將ip * port作為請求條件,現改為傳固有參數進來 * * @param text * @throws Exception */ public static String sendBySocket(String text, String ip, int port) throws Exception { log.info("開始建立socket連接"); Socket socket = new Socket(ip, port); InputStream is = socket.getInputStream(); InputStreamReader isr = new InputStreamReader(is, "GBK"); // 2.獲取客戶端輸出流 OutputStream dos = socket.getOutputStream(); log.info("連上服務端"); // 3.向服務端發送消息 dos.write(text.getBytes()); dos.flush(); log.info("成功向服務器發送消息"); // 4.獲取輸入流,並讀取服務器端的響應信息 BufferedReader br = new BufferedReader(isr); String returnInfo = br.readLine(); log.info("服務器端返回數據為:" + returnInfo); // 4.關閉資源 br.close(); isr.close(); is.close(); dos.close(); socket.close(); return returnInfo; }
Java中socket接口調用