Java Socket編程和TCP/IP協議

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編程

一、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編程

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長鏈接的文章,基本上都是闡述原理的,有沒有具體代碼演示的?

相關文章
相關標籤/搜索