一、理解socket
1.1什么是socket?
- socket通常也稱作"套接字",用於描述IP地址和端口,是一個通信鏈的句柄。應用程序通常通過"套接字"向網絡發出請求或者應答網絡請求。
- Socket和ServerSocket類庫位於java.net包中。ServerSocket用於服務器端,Socket是建立網絡連接時使用的。在連接成功時,應用程序兩端都會產生一個Socket實例,操作這個實例,完成所需的會話。對於一個網絡連接來說,套接字是平等的,並沒有差別,不因為在服務器端或在客戶端而產生不同級別。不管是Socket還是ServerSocket它們的工作都是通過Socket類及其子類完成的。
1.2重要的socket
- java.net.Socket繼承於java.lang.Object,有八個構造器,其方法並不多,下面介紹使用最頻繁的三個方法:
1.accept方法
用於產生"阻塞",直到接收到一個連接,並且返回一個客戶端的Socket對象實例。"阻塞"是一個術語,它使程序運行暫時"停留"在這個地方,直到一個會話產生,然后程序繼續;通常"阻塞"是由循環產生的。
2.getInputStream方法
連接的另一端將得到輸入,同時返回一個OutputStream對象實例。
注意:其中getInputStream和getOutputStream方法均會產生一個IOException,它必須被捕獲,因為它們返回的流對象,通常都會被另一個流對象使用。
3.getOutputStream方法
連接的另一端將得到輸入,同時返回一個OutputStream對象實例。
注意:其中getInputStream和getOutputStream方法均會產生一個IOException,它必須被捕獲,因為它們返回的流對象,通常都會被另一個流對象使用。
1.3Socket通信原理
服務器:使用ServerSocket監聽指定的端口,端口可以隨意指定(由於1024以下的端口通常屬於保留端口,在一些操作系統中不可以隨意使用,所以建議使用大於1024的端口),等待客戶連接請求,客戶連接后,會話產生;在完成會話后,關閉連接。
客戶端:使用Socket對網絡上某一個服務器的某一個端口發出連接請求,一旦連接成功,打開會話;會話完成后,關閉Socket。客戶端不需要指定打開的端口,通常臨時的動態的分配一個1024以上的端口。
ServerSocket類
ServerSocket myListener = new ServerSocket(600);
提供監聽服務的端口是600,不同服務之間通過端口來區別。為了隨時監聽可能的Client端的請求,執行如下語句:
Socket linkSockt = myListener.accept();這個方法執行將使得Server端處於等待狀態,直到接收一個來自Client端的請求,並返回一個與Client通信的Socket對象。
Server端與Client端連接后,就實現了相互讀寫數據,結束通信執行:
myListener.close();
Socket類
Client需從Server獲取服務時,應創建一個Socket對象:
Socket mySocket = new Socket(host,port);
連通后,利用Socket類方法getOutputStream()獲取(write)輸出流,和getInputStream()獲取(read)輸入流。結束通信同樣是
mySocket.close();
ServerSocket一般僅用於設置端口號和監聽,真正進行通信的是Server端的Socket與Client端的Socket,在ServerSocket進行accept后,就將主動權轉讓給Server端的Socket。
二、socket編程范例及運行過程!
流程圖如下:
客戶端代碼:
1 import java.net.Socket;
2 import java.io.InputStream;
3 import java.io.OutputStream;
4 import java.io.PrintWriter;
5 import java.io.BufferedReader;
6 import java.io.InputStreamReader;
7 import java.io.IOException;
8 import java.net.UnknownHostException;
9
10 public class ClientText {
11
12 public static final String ip="127.0.32.42";
13 public static int port=7890;
14 private Socket client_s;
15
16 public ClientText(){
17 try{
18 client_s=new Socket(ip,port);
19 }catch(UnknownHostException e){
20 e.printStackTrace();
21 }catch(IOException c){
22 c.printStackTrace();
23 }
24 }
25
26 public void setConnection() throws IOException{
27 InputStream is;
28 OutputStream os;
29 try{
30 is=client_s.getInputStream();
31 os=client_s.getOutputStream();
32 BufferedReader sys_br=new BufferedReader(new InputStreamReader(System.in));
33 BufferedReader client_br=new BufferedReader(new InputStreamReader(is));
34 PrintWriter client_pw=new PrintWriter(os,true);
35 String warnStr=null;
36 if((warnStr=client_br.readLine())!=null){
37 System.out.println(warnStr);
38 }
39 while((warnStr=sys_br.readLine())!=null){
40 client_pw.println(warnStr);
41 break;
42 }
43 }catch(IOException e){
44 e.printStackTrace();
45 }
46 }
47
48 public static void main(String[] args) {
49 // TODO 自動生成的方法存根
50 ClientText myclient=new ClientText();
51 try {
52 myclient.setConnection();
53 } catch (IOException e) {
54 // TODO 自動生成的 catch 塊
55 e.printStackTrace();
56 }
57 }
58
59 }
服務端代碼:
1 import java.io.IOException;
2 import java.net.ServerSocket;
3 import java.net.Socket;
4 import java.io.InputStream;
5 import java.io.OutputStream;
6 import java.io.InputStreamReader;
7 import java.io.PrintWriter;
8 import java.io.BufferedReader;
9
10 public class ServerText{
11
12 private ServerSocket ss;
13 public static final int port=7890;
14
15 public ServerText(){
16 try{
17 ss=new ServerSocket(port);
18 }catch(IOException e){
19 e.printStackTrace();
20 }
21 }
22
23 public void setConnection()throws IOException{
24 Socket server_s;
25 OutputStream os;
26 InputStream is;
27 try{
28 //服務器程序陷入阻塞狀態,隨時接受客戶端的鏈接
29 server_s=ss.accept();
30 //接收並連接之后
31 os=server_s.getOutputStream();
32 is=server_s.getInputStream();
33 //給客戶端發送數據
34 PrintWriter server_pw=new PrintWriter(os,true);
35 //接收客戶端的數據
36 BufferedReader server_br=new BufferedReader(new InputStreamReader(is));
37 String msg=null;
38 server_pw.println("連接成功,請輸入一些數據傳遞到服務端");
39 if((msg=server_br.readLine())!=null){
40 System.out.println("客戶端傳遞過來的數據為:"+msg);
41 server_pw.println("數據傳輸成功");
42 }else{
43 server_pw.println("數據傳輸失敗,出現錯誤");
44 }
45 }catch(IOException e){
46 e.printStackTrace();
47 }
48 }
49
50 public static void main(String args[]) throws IOException{
51 ServerText server_text=new ServerText();
52 server_text.setConnection();
53
54 }
55 }
運行結果:
客戶端:
服務端:
以上就是簡單的socket的通信過程。