Socket編程java
1、網絡基礎知識android
一、兩臺計算機間進行通信須要如下三個條件:
IP地址、協議、端口號編程
二、TCP/IP協議:
是目前世界上應用最爲普遍的協議,是以TCP和IP爲基礎的不一樣層次上多個協議的集合,也成TCP/IP協議族、或TCP/IP協議棧
TCP:Transmission Control Protocol 傳輸控制協議
IP:Internet Protocol 互聯網協議服務器
三、TCP/IP五層模型
應用層:HTTP、FTP、SMTP、Telnet等
傳輸層:TCP、UDP
網絡層:IP,ICMP,OSPF,EIGRP,IGMP
數據鏈路層:SLIP,CSLIP,PPP,MTU
物理層:網線、雙絞線、網卡等 網絡
四、IP地址
爲實現網絡中不一樣計算機之間的通訊,每臺計算機都必須有一個惟一的標識—IP地址。
32位二進制多線程
五、端口
區分一臺主機的多個不一樣應用程序,端口號範圍爲0-65535,其中0-1023位爲系統保留。
如:HTTP:80 FTP:21 Telnet:23
IP地址+端口號組成了所謂的Socket,Socket是網絡上運行的程序之間雙向通訊鏈路的終結點,是TCP和UDP的基礎socket
六、Socket套接字:
網絡上具備惟一標識的IP地址和端口組合在一塊兒才能構成惟一能識別的標識符套接字。
Socket原理機制:
通訊的兩端都有Socket
網絡通訊其實就是Socket間的通訊
數據在兩個Socket間經過IO傳輸ui
七、Java中的網絡支持
針對網絡通訊的不一樣層次,Java提供了不一樣的API,其提供的網絡功能有四大類:
InetAddress:用於標識網絡上的硬件資源,主要是IP地址
URL:統一資源定位符,經過URL能夠直接讀取或寫入網絡上的數據
Sockets:使用TCP協議實現的網絡通訊Socket相關的類
Datagram:使用UDP協議,將數據保存在用戶數據報中,經過網絡進行通訊。this
一、TCP協議是面向鏈接的、可靠的、有序的、以字節流的方式發送數據,經過三次握手方式創建鏈接,造成傳輸數據的通道,在鏈接中進行大量數據的傳輸,效率會稍低spa
二、Java中基於TCP協議實現網絡通訊的類
客戶端的Socket類
服務器端的ServerSocket類
三、Socket通訊的步驟
① 建立ServerSocket和Socket
② 打開鏈接到Socket的輸入/輸出流
③ 按照協議對Socket進行讀/寫操做
④ 關閉輸入輸出流、關閉Socket
四、服務器端:
① 建立ServerSocket對象,綁定監聽端口
② 經過accept()方法監聽客戶端請求
③ 鏈接創建後,經過輸入流讀取客戶端發送的請求信息
④ 經過輸出流向客戶端發送語音信息
⑤ 關閉相關資源
import java.io.DataInputStream; import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; public class TCPServerDemo { private ServerSocket serverSocket; private DataInputStream dataInputStream; public void startServer(){ Socket socket =null; try { serverSocket = new ServerSocket(10003); socket = serverSocket.accept(); dataInputStream = new DataInputStream(socket.getInputStream()); GetMessageFromClient(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); }finally{ if(socket!=null){ try{ socket.close(); }catch(IOException e) { e.printStackTrace(); } } } } private void GetMessageFromClient(){ try { //獲取消息的長度 int length = dataInputStream.read(); //獲取消息 byte[] body = new byte[length]; dataInputStream.read(body); String message = new String(body); System.out.println("客戶端說:"+message); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public static void main(String[] args) { // TODO Auto-generated method stub TCPServerDemo server = new TCPServerDemo(); server.startServer(); } }
五、客戶端:
① 建立Socket對象,指明須要鏈接的服務器的地址和端口號
② 鏈接創建後,經過輸出流想服務器端發送請求信息
③ 經過輸入流獲取服務器響應的信息
④ 關閉響應資源
import java.io.IOException; import java.io.OutputStream; import java.net.Socket; import java.net.UnknownHostException; public class TCPClientDemo { public static void main(String[] args) throws UnknownHostException, IOException { // TODO Auto-generated method stub //1.創建TCP鏈接 String ip="10.105.53.65"; //服務器端ip地址 int port=10002; //端口號 Socket sck=new Socket(ip,port); //2.傳輸內容 String content="這是一個java模擬客戶端"; byte[] bstream=content.getBytes("GBK"); //轉化爲字節流 OutputStream os=sck.getOutputStream(); //輸出流 os.write(bstream); //3.關閉鏈接 sck.close(); } }
六、應用多線程實現服務器與多客戶端之間的通訊
① 服務器端建立ServerSocket,循環調用accept()等待客戶端鏈接
② 客戶端建立一個socket並請求和服務器端鏈接
③ 服務器端接受客戶端的請求,建立socket與該客戶創建專線鏈接
④ 創建鏈接的兩個socket在一個單獨的線程上對話
⑤ 服務器端繼續等待新的鏈接
//服務器線程處理 //和本線程相關的socket Socket socket =null; // public serverThread(Socket socket){ this.socket = socket; } publicvoid run(){ //服務器處理代碼 ServerSocket serverSocket =newServerSocket(10086); Socket socket =null; int count =0;//記錄客戶端的數量 while(true){ socket = serverScoket.accept(); ServerThread serverThread =newServerThread(socket); serverThread.start(); count++; System.out.println("客戶端鏈接的數量:"+count); } }
UDP協議(用戶數據報協議)是無鏈接的、不可靠的、無序的,速度快
進行數據傳輸時,首先將要傳輸的數據定義成數據報(Datagram),大小限制在64K,在數據報中指明數據索要達到的Socket(主機地址和端口號),而後再將數據報發送出去
DatagramPacket類:表示數據報包
DatagramSocket類:進行端到端通訊的類
一、服務器端實現步驟
① 建立DatagramSocket,指定端口號
② 建立DatagramPacket
③ 接受客戶端發送的數據信息
④ 讀取數據
//服務器端,實現基於UDP的用戶登陸 //一、建立服務器端DatagramSocket,指定端口 DatagramSocket socket =new datagramSocket(10010); //二、建立數據報,用於接受客戶端發送的數據 byte[] data =newbyte[1024];// DatagramPacket packet =newDatagramPacket(data,data.length); //三、接受客戶端發送的數據 socket.receive(packet);//此方法在接受數據報以前會一致阻塞 //四、讀取數據 String info =newString(data,o,data.length); System.out.println("我是服務器,客戶端告訴我"+info); //========================================================= //向客戶端響應數據 //一、定義客戶端的地址、端口號、數據 InetAddress address = packet.getAddress(); int port = packet.getPort(); byte[] data2 = "歡迎您!".geyBytes(); //二、建立數據報,包含響應的數據信息 DatagramPacket packet2 = new DatagramPacket(data2,data2.length,address,port); //三、響應客戶端 socket.send(packet2); //四、關閉資源 socket.close();
二、客戶端實現步驟
① 定義發送信息
② 建立DatagramPacket,包含將要發送的信息
③ 建立DatagramSocket
④ 發送數據
//客戶端 //一、定義服務器的地址、端口號、數據 InetAddress address =InetAddress.getByName("localhost"); int port =10010; byte[] data ="用戶名:admin;密碼:123".getBytes(); //二、建立數據報,包含發送的數據信息 DatagramPacket packet = newDatagramPacket(data,data,length,address,port); //三、建立DatagramSocket對象 DatagramSocket socket =newDatagramSocket(); //四、向服務器發送數據 socket.send(packet); //接受服務器端響應數據 //====================================== //一、建立數據報,用於接受服務器端響應數據 byte[] data2 = new byte[1024]; DatagramPacket packet2 = new DatagramPacket(data2,data2.length); //二、接受服務器響應的數據 socket.receive(packet2); String raply = new String(data2,0,packet2.getLenth()); System.out.println("我是客戶端,服務器說:"+reply); //四、關閉資源 socket.close();
如何實現android和服務器長鏈接?
咱們有時候有這種需求,即咱們的android客戶端要始終保持與服務端的鏈接,當服務端有任務或消息發送到android客戶端的時候就發送,沒有任務或消息的時候不發送但要保持這個鏈接,一旦有任務則開發發送,而咱們的android客戶端則要保持一個時刻接收任務或消息的狀態。。。這個時候咱們經過socket來實現這種需求【固然你也能夠採用http輪詢的方式來不斷的從客戶端個請求服務端,這樣作有必定的弊端】
實現原理:
1:android客戶端經過service在後臺經過servreScoket不斷的accept,一旦有相應的socket到達,則啓動一個線程去處理
2::在線程中處理完返回給咱們android客戶端的消息或任務以後,要將這種結果表如今ui上,這個步驟方法就比較多了,例如你能夠發一個廣播來通知ui,或者你能夠經過一個static的handler來處理
Android保持長鏈接的代碼如何寫?最近看了不少關於Android長鏈接的文章,基本上都是闡述原理的,有沒有具體代碼演示的?