1. 程式人生 > >Socket 通訊原理(Android客戶端和伺服器以TCP&&UDP方式互通)

Socket 通訊原理(Android客戶端和伺服器以TCP&&UDP方式互通)

ZERO、前言

有關通訊原理內容是在網上或百科整理得到,程式碼部分為本人所寫,如果不當,還望指教。

一、Socket通訊簡介 

Android與伺服器的通訊方式主要有兩種,一是Http通訊,一是Socket通訊。兩者的最大差異在於,http連線使用的是“請求—響應方式”,即在請求時建立連線通道,當客戶端向伺服器傳送請求後,伺服器端才能向客戶端返回資料。而Socket通訊則是在雙方建立起連線後就可以直接進行資料的傳輸,在連線時可實現資訊的主動推送,而不需要每次由客戶端想伺服器傳送請求。 那麼,什麼是socket?Socket又稱套接字,在程式內部提供了與外界通訊的埠,即埠通訊。通過建立socket連線,可為通訊雙方的資料傳輸傳提供通道。socket的主要特點有資料丟失率低,使用簡單且易於移植。


1.1什麼是Socket Socket
是一種抽象層,應用程式通過它來發送和接收資料,使用Socket可以將應用程式新增到網路中,與處於同一網路中的其他應用程式進行通訊。簡單來說,Socket提供了程式內部與外界通訊的埠併為通訊雙方的提供了資料傳輸通道。


 1.2Socket的分類
 根據不同的的底層協議,Socket的實現是多樣化的。本指南中只介紹TCP/IP協議族的內容,在這個協議族當中主要的Socket型別為流套接字(streamsocket)和資料報套接字(datagramsocket)。流套接字將TCP作為其端對端協議,提供了一個可信賴的位元組流服務。資料報套接字使用UDP協議,提供資料打包傳送服務。 下面,我們來認識一下這兩種Socket型別的基本實現模型。

二、Socket 基本通訊模型


三、Socket基本實現原理

 3.1基於TCP協議的Socket 
伺服器端首先宣告一個ServerSocket物件並且指定埠號,然後呼叫Serversocket的accept()方法接收客戶端的資料。accept()方法在沒有資料進行接收的處於堵塞狀態。(Socketsocket=serversocket.accept()),一旦接收到資料,通過inputstream讀取接收的資料。
 客戶端建立一個Socket物件,指定伺服器端的ip地址和埠號(Socketsocket=newSocket("172.168.10.108",8080);),通過inputstream讀取資料,獲取伺服器發出的資料(OutputStreamoutputstream=socket.getOutputStream()),最後將要傳送的資料寫入到outputstream即可進行TCP協議的socket資料傳輸。
3.2基於UDP協議的資料傳輸 


伺服器端首先建立一個DatagramSocket物件,並且指點監聽的埠。接下來建立一個空的DatagramSocket物件用於接收資料(bytedata[]=newbyte[1024;]DatagramSocketpacket=newDatagramSocket(data,data.length)),使用DatagramSocket的receive方法接收客戶端傳送的資料,receive()與serversocket的accepet()類似,在沒有資料進行接收的處於堵塞狀態。
客戶端也建立個DatagramSocket物件,並且指點監聽的埠。接下來建立一個InetAddress物件,這個物件類似與一個網路的傳送地址(InetAddressserveraddress=InetAddress.getByName("172.168.1.120")).定義要傳送的一個字串,建立一個DatagramPacket物件,並制定要講這個資料報包傳送到網路的那個地址以及埠號,最後使用DatagramSocket的物件的send()傳送資料。*(Stringstr="hello";bytedata[]=str.getByte();DatagramPacketpacket=new DatagramPacket(data,data.length,serveraddress,4567);socket.send(packet);)

四、android 實現socket簡單通訊

前言:新增許可權

<!--允許應用程式改變網路狀態-->  
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>  
  
<!--允許應用程式改變WIFI連線狀態-->  
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>  
  
<!--允許應用程式訪問有關的網路資訊-->  
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>  
  
<!--允許應用程式訪問WIFI網絡卡的網路資訊-->  
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>  
  
<!--允許應用程式完全使用網路-->  
<uses-permission android:name="android.permission.INTERNET"/>  

4.1使用TCP協議通訊

android端實現:

	protected void connectServerWithTCPSocket() {

		Socket socket;
		try {// 建立一個Socket物件,並指定服務端的IP及埠號
			socket = new Socket("192.168.1.32", 1989);
			// 建立一個InputStream使用者讀取要傳送的檔案。
			InputStream inputStream = new FileInputStream("e://a.txt");
			// 獲取Socket的OutputStream物件用於傳送資料。
			OutputStream outputStream = socket.getOutputStream();
			// 建立一個byte型別的buffer位元組陣列,用於存放讀取的本地檔案
			byte buffer[] = new byte[4 * 1024];
			int temp = 0;
			// 迴圈讀取檔案
			while ((temp = inputStream.read(buffer)) != -1) {
				// 把資料寫入到OuputStream物件中
				outputStream.write(buffer, 0, temp);
			}
			// 傳送讀取的資料到服務端
			outputStream.flush();

			/** 或建立一個報文,使用BufferedWriter寫入,看你的需求 **/
//			String socketData = "[2143213;21343fjks;213]";
//			BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(
//					socket.getOutputStream()));
//			writer.write(socketData.replace("\n", " ") + "\n");
//			writer.flush();
			/************************************************/
		} catch (UnknownHostException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}

	}

伺服器端簡單實現:
	public void ServerReceviedByTcp() {
		// 宣告一個ServerSocket物件
		ServerSocket serverSocket = null;
		try {
			// 建立一個ServerSocket物件,並讓這個Socket在1989埠監聽
			serverSocket = new ServerSocket(1989);
			// 呼叫ServerSocket的accept()方法,接受客戶端所傳送的請求,
			// 如果客戶端沒有傳送資料,那麼該執行緒就停滯不繼續
			Socket socket = serverSocket.accept();
			// 從Socket當中得到InputStream物件
			InputStream inputStream = socket.getInputStream();
			byte buffer[] = new byte[1024 * 4];
			int temp = 0;
			// 從InputStream當中讀取客戶端所傳送的資料
			while ((temp = inputStream.read(buffer)) != -1) {
				System.out.println(new String(buffer, 0, temp));
			}
			serverSocket.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

4.2使用UDP協議通訊

客戶端傳送資料實現:

	protected void connectServerWithUDPSocket() {
		
		DatagramSocket socket;
		try {
			//建立DatagramSocket物件並指定一個埠號,注意,如果客戶端需要接收伺服器的返回資料,
			//還需要使用這個埠號來receive,所以一定要記住
			socket = new DatagramSocket(1985);
			//使用InetAddress(Inet4Address).getByName把IP地址轉換為網路地址  
			InetAddress serverAddress = InetAddress.getByName("192.168.1.32");
			//Inet4Address serverAddress = (Inet4Address) Inet4Address.getByName("192.168.1.32");  
			String str = "[2143213;21343fjks;213]";//設定要傳送的報文  
			byte data[] = str.getBytes();//把字串str字串轉換為位元組陣列  
			//建立一個DatagramPacket物件,用於傳送資料。  
			//引數一:要傳送的資料  引數二:資料的長度  引數三:服務端的網路地址  引數四:伺服器端埠號 
			DatagramPacket packet = new DatagramPacket(data, data.length ,serverAddress ,10025);  
			socket.send(packet);//把資料傳送到服務端。  
		} catch (SocketException e) {
			e.printStackTrace();
		} catch (UnknownHostException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}  
	}

客戶端接收伺服器返回的資料:
	public void ReceiveServerSocketData() {
		DatagramSocket socket;
		try {
			//例項化的埠號要和傳送時的socket一致,否則收不到data
			socket = new DatagramSocket(1985);
			byte data[] = new byte[4 * 1024];
			//引數一:要接受的data 引數二:data的長度
			DatagramPacket packet = new DatagramPacket(data, data.length);
			socket.receive(packet);
			//把接收到的data轉換為String字串
			String result = new String(packet.getData(), packet.getOffset(),
					packet.getLength());
			socket.close();//不使用了記得要關閉
			System.out.println("the number of reveived Socket is  :" + flag
					+ "udpData:" + result);
		} catch (SocketException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

伺服器接收客戶端實現:
	public void ServerReceviedByUdp(){
		//建立一個DatagramSocket物件,並指定監聽埠。(UDP使用DatagramSocket)  
		DatagramSocket socket;
		try {
			socket = new DatagramSocket(10025);
			//建立一個byte型別的陣列,用於存放接收到得資料  
			byte data[] = new byte[4*1024];  
			//建立一個DatagramPacket物件,並指定DatagramPacket物件的大小  
			DatagramPacket packet = new DatagramPacket(data,data.length);  
			//讀取接收到得資料  
			socket.receive(packet);  
			//把客戶端傳送的資料轉換為字串。  
			//使用三個引數的String方法。引數一:資料包 引數二:起始位置 引數三:資料包長  
			String result = new String(packet.getData(),packet.getOffset() ,packet.getLength());  
		} catch (SocketException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}  
	}


五、總結:

使用UDP方式android端和伺服器端接收可以看出,其實android端和伺服器端的傳送和接收大庭相徑,只要埠號正確了,相互通訊就沒有問題,TCP使用的是流的方式傳送,UDP是以包的形式傳送。

demo地址:http://download.csdn.net/detail/mad1989/5626975

20130621

相關推薦

Socket 通訊原理(Android客戶伺服器TCP&&UDP方式互通)

ZERO、前言 有關通訊原理內容是在網上或百科整理得到,程式碼部分為本人所寫,如果不當,還望指教。 一、Socket通訊簡介  Android與伺服器的通訊方式主要有兩種,一是Http通訊,一是Socket通訊。兩者的最大差異在於,http連線使用的是“請求—響應方式

socket 通訊寫出客戶伺服器通訊 , 要求客戶傳送資料後能夠回顯相同的資料

比較基礎的一個服務端客戶端互相通訊的程式/** * @author john socket 的伺服器端,接收到資料後列印到控制檯 的資料 * */ public class ServiceSocket_1 { public static void main(

Android客戶伺服器交換資料的一種方案

由於很多因素使得客戶端和伺服器之間互動的一些資料都要經過加密,為了方便,很多使用非對稱的加密演算法進行加密,其中RSA演算法成為首選。下面說說在Android客戶端怎中怎麼應用這種加密方案。 首先在我們Android客戶端啟動應用程式的時候,我們先請求一個伺服器,讓服務將R

網路通訊,實現客戶伺服器通訊

      write(new_fd,buf,strlen(buf));    }    }else{      perror("fork");    }}int main(int argc,char *argv[]){    if(argc!=3){       printf("Usage ./server

Android客戶伺服器資料互動的第四種方法

        網上有很多例子來演示Android客戶端和伺服器端資料如何實現互動不過這些例子大多比較繁雜,對於初學者來說這是不利的,現在介紹幾種程式碼簡單、邏輯清晰的互動例子,本篇部落格介紹第四種:         一、伺服器端:         程式碼1:新增名為“A

網路程式設計(InetAddress類、SocketServerSocket、實現客戶伺服器之間的雙向通訊

網路程式設計的底層是IO,通過IO將一臺計算機中的資料傳送到另一臺計算機中。傳送的時候,要知道接受方的地址,該地址即為IP地址。知道IP地址後即可進行傳送。A向B發訊息,訊息是發過去了,但是B要怎樣接受呢?因此定義了埠,B監聽了A所使用的埠。A發的訊息中含有埠號,當B接受到訊息時,知道了埠號

socket通訊客戶伺服器的簡單實現

什麼是socket? socket最開始的含義是一個地址和埠對(ip, port)。Socket又稱"套接字",應用程式通常通過"套接字"向網路發出請求或者應答網路請求。 socket地址API:它唯一的表示了使用tcp通訊的一端,也可以將其理解成socket地址。 socket

java socket客戶伺服器通訊

    所謂可以多客戶端,就是需要在伺服器端進行多執行緒程式設計,每一個客戶端對應一個執行緒。如果要實現時時通訊和話,無論是客戶端還是伺服器端都要至少兩個執行緒,主執行緒進行傳送資訊,子執行緒進行獲取資訊,這樣可以保證時時通訊.下面貼出我的程式碼:客戶端:package

C# 利用Socket類實現客戶伺服器之間的通訊,可在本機之間實現資訊互動

利用Socket類實現了本機之間的客戶端與服務端的資訊互動。 伺服器: using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using

Socket通訊客戶伺服器對話

科技改變時代…… 1/Socket 1,什麼是Socket 網路上的兩個程式通過一個雙向的通訊連線實現資料的交換,這個雙向鏈路的一端稱為一個Socket。Socket通常用來實現客戶方和服務方的連線。Socket是TCP/IP協議的一個十分流行的程

java socket 客戶伺服器互相通訊(聊天)

客戶端: package com.lzx.socket; import java.io.BufferedReader; import java.io.IOException; import jav

Android客戶伺服器進行通訊

在Android開發中,經常使用到與後臺進行互動,後臺人員給你一個URL,Android使用HttpURLConnection得到後臺返回的資料。這些任務是開發中經常遇到的。這裡,我們自己搭建一個簡易的後臺,來實現Android客戶端與後臺的互動。 首先,後臺

linux下socket實現多個客戶伺服器通訊

學習完《UNIX環境高階程式設計》套接字一章的內容之後,自己實現了單個客戶端與伺服器的通訊程式,後面想想要是多個客戶端如何與伺服器通訊呢?這就有了這篇文章。 伺服器端程式: #include<stdio.h> #include <stdlib.h&g

Android客戶伺服器之間傳輸資料加密

       Android客戶端與伺服器進行資料傳輸時,一般會涉及到兩類資料的加密情況,一類是隻有建立者才能知道的資料,比如密碼;另一類是其他比較重要的,但是可以逆向解密的資料。        第一類:密碼類的資料,為了讓使用者放心註冊,密碼類的資料的加密一般都是經過

java使用UDP來進行客戶伺服器通訊的簡單例子

1:客戶端程式 package com.pb.udp; import java.io.IOException; import java.net.DatagramPacket; import java.net.InetAddress; import java.net.Unk

Android客戶伺服器連線通訊

遇到一個小問題: 第一個Activity與伺服器連線時能夠成功連線 但是利用跳轉之後的Activity與伺服器連線一直不成功 解決: 在登陸時呼叫connect方法與伺服器連線,Activity跳轉之後就會斷開連線,因為連線函式是直

android上傳大檔案到伺服器客戶伺服器程式碼

使用一般的上傳方法一般上傳不能超過2m的檔案,也非常容易中斷和出錯,於是本人打算使用xutils框架進行檔案上傳開發,話不多說直接上原始碼 首先要下載這個類庫的jar包,地址:https://github.com/wyouflf/xUtils android端程式碼: 新增

Android客戶伺服器的資料通訊中文亂碼問題

         做了一個小的專案用到了客戶端與伺服器端通訊,然而隨之而來的問題就有了。 那就是中文亂碼問題,由伺服器端向客戶端或者客戶端向伺服器端傳送資料時,中文變為問號---?????---。  

LInux中利用執行緒實現多個客戶伺服器進行通訊

上一篇博文講了如何利用子程序實現多個客戶端和伺服器端進行通訊, 那麼,這一篇部落格就來實現一下如何利用執行緒實現多個客戶端和伺服器端進行通訊 程式碼實現: ser1.c #include <

什麼是socket?什麼是socket的長、短連線?java如何簡單實現socket客戶伺服器

*socket就是套接字,是一種通訊方式!採用這種方式可以實現客戶端和伺服器之間的通訊! 百度百科的解釋:        Socket的英文原義是“孔”或“插座”。作為BSD UNIX的程序通訊機制,取後一種意思。通常也稱作"套接字",用於描述IP地址和埠,是一個通訊鏈的控