Android開發 socket

這幾天徹底被socket 卡住了, 主要緣由就是就ip,Socket通訊主要有倆種,1,TCP,2,UDPjava

一,何時SOCKET通訊:android

你常常聽到人們談論着 「socket」,或許你還不知道它的確切含義。如今讓我告訴你:它是使用 標準Unix 文件描述 符 (file descriptor) 和其它程序通信的方式。什麼?你也許聽到一些Unix高手(hacker)這樣說過:「呀,Unix中的一切就 是文件!」那個傢伙也許正在說到一個事實:Unix 程序在執行任何形式的 I/O 的時候,程序是在讀或者寫一個文件描述符。一個文件描述符只是一個和 打開的文件相關聯的整數。可是(注意後面的話),這個文件多是一個網絡鏈接,FIFO,管道,終端,磁盤上的文件或者什麼其它的東西。Unix 中全部 的東西就是文件!因此,你想和Internet上別的程序通信的時候,你將要使用到文件描述符。你必須理解剛纔的話。如今你腦海中或許冒出這樣的念頭: 「那麼我從哪裏獲得網絡通信的文件描述符呢?」,這個問題不管如何我都要回答:你利用系統調用 socket(),它返回套接字描述 符 (socket descriptor),而後你再經過它來進行send() 和 recv()調用。「可是...」,你可能有很大的疑惑,「若是它 是個文件描述符,那麼爲什 麼不用通常調用read()和write()來進行套接字通信?」簡單的答案是:「你可使用!」。詳細的答案是:「你能夠, 可是使用send()和recv()讓你更好的控制數據傳輸。」存在這樣一個狀況:在咱們的世界上,有不少種套接字。有DARPA Internet 地 址 (Internet 套接字),本地節點的路徑名 (Unix套接字),CCITT X.25地址 (你能夠將X.25 套接字徹底忽略)。也許在你 的Unix 機器上還有其它的。咱們在這裏只講第一種:Internet 套接字。  瀏覽器

TCP採用的是3次握手協議,因此通常狀況下,對於一些比較重要數據,應該使用TCP 進行開發,  固然用UDP是比較簡單的他們之間的區別在於:服務器

有什麼在使用流式套接字?你可能據說過 telnet,不是嗎?它就使用流式套接字。你須要你所輸入的字符按順序到達,不是嗎?同 樣,WWW瀏覽器使用的 HTTP 協議也使用它們來下載頁面。實際上,當你經過端口80 telnet 到一個 WWW 站點,而後輸 入 「GET pagename」 的時候,你也能夠獲得 HTML 的內容。爲何流式套接字能夠達到高質量的數據傳輸?這是由於它使用了「傳輸控制協 議 (The Transmission Control Protocol)」,也叫 「TCP」 (請參考 RFC-793 得到詳細資 料。)TCP 控制你的數據按順序到達而且沒有錯 
誤。你也許聽到 「TCP」 是由於聽到過 「TCP/IP」。這裏的 IP 是指「Internet 協議」(請參考 RFC-791。) IP 只是處理 Internet 路由而已。  
    那麼數據報套接字呢?爲何它叫無鏈接呢?爲何它是不可靠的呢?有這樣的一些事實:若是你發送一個數據報,它可能會到達,它可能次序顛 倒了。若是它到達,那麼在這個包的內部是無錯誤的。數據報也使用 IP 做路由,可是它不使用 TCP。它使用「用戶數據報協 議 (User Datagram Protocol)」,也叫 「UDP」 (請參考 RFC-768。)  
    爲何它們是無鏈接的呢?主要是由於它並不象流式套接字那樣維持一個鏈接。你只要創建一個包,構造一個有目標信息的IP 頭,而後發出去。無需鏈接。它們一般使用於傳輸包-包信息。簡單的應用程序有:tftp, bootp等等。 
網絡

    你也許會想:「假如數據丟失了這些程序如何正常工做?」個人朋友,每一個程序在 UDP 上有本身的協議。例如,tftp 協議每發出的一 個被接受到包,收到者必須發回一個包來講「我收到了!」 (一個「命令正確應答」也叫「ACK」 包)。若是在必定時間內(例如5秒),發送方沒有收到應 答,它將從新發送,直到獲得 ACK。這一ACK過程在實現 SOCK_DGRAM 應用程序的時候很是重要。socket

主要程序:函數

服務器端:TCP oop

                        //建立一個ServerSocket對象,並讓這個Socket在4567端口監聽spa

serverSocket = new ServerSocket(4567);server

//調用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));

客戶端的TCP: //建立一個Socket對象,指定服務器端的IP地址和端口號

Socket socket = new Socket(ip,4567);

System.out.println("Connect TCP");

//使用InputStream讀取硬盤上的文件

InputStream inputStream = new FileInputStream("d://words.txt");

//從Socket當中獲得OutputStream

OutputStream outputStream = socket.getOutputStream();

byte buffer [] = new byte[4*1024];

int temp = 0 ;

//將InputStream當中的數據取出,並寫入到OutputStream當中

while((temp = inputStream.read(buffer)) != -1){

outputStream.write(buffer, 0, temp);

服務器端的UDP:

//建立一個DatagtamSocket對象,並制定監聽的端口號 (0-65535之間)

    DatagramSocket socket = new DatagramSocket(2888);

    byte data [] = new byte[1024];

    //建立一個空的DatagramPacket對象,用來接收從客戶端發送來的數據

    DatagramPacket packet = new DatagramPacket(data,data.length);

    //使用receive方法接收客戶端所發送的數據

    //這是一個阻塞的方法。  

    socket.receive(packet);

   

    //下面的java.lang.String.String(byte[] data, int offset, int byteCount)

    String result = new String(packet.getData(),packet.getOffset(),packet.getLength());

    System.out.println("result----->"+result);

客戶端的UDP:

System.out.println("IP---->"+ip);

//建立一個InetAddreess This class represents an Internet Protocol (IP) address. 

//UDP發送數據如同寄信同樣,InetAddress就是寄到的地址

InetAddress serverAddress = InetAddress.getByName(ip);

String str ="hello";

byte data [] = str.getBytes();

//建立一個DatagramPacket對象,並制定要講這個數據包發送到網絡中的哪一個地址,以及端口號

DatagramPacket packet = new DatagramPacket(data,data.length,serverAddress,2888);

//調用socket對象的send方法,發送數據

socket.send(packet);

System.out.println("UDP send Over");


問題就出如今ip中,這幾天不論是真機仍是虛擬機,都沒法經過,卡了好長時間,終於,剛纔頓悟了,這裏的IP是服務器端的IP,而這個程序裏服務器就是android真機,因此要獲得真機的IP,就要在服務器的程序中獲得,這裏用了一個函數,

 

public static String getIp(), 將獲得的IP, 打印出來,而後在客戶端使用。

就是這麼一個簡答的問題,糾結了幾天,終於出來了,嘿嘿,慶祝一個、

 public static String getIp(){  

      String localip=null;

     String netip=null;

     try {  

     Enumeration<NetworkInterface> netInterfaces = NetworkInterface.getNetworkInterfaces();  

     InetAddress ip = null;  

     boolean finded=false;  

     while(netInterfaces.hasMoreElements() && !finded){  

     NetworkInterface ni=netInterfaces.nextElement();  

     Enumeration<InetAddress> address=ni.getInetAddresses();  

     while(address.hasMoreElements()){  

     ip=address.nextElement();  

     if( !ip.isSiteLocalAddress() && !ip.isLoopbackAddress() && ip.getHostAddress().indexOf(":")==-1){  

     netip=ip.getHostAddress();  

     finded=true;  

     break;  

     }else if(ip.isSiteLocalAddress() && !ip.isLoopbackAddress() && ip.getHostAddress().indexOf(":")==-1){

     localip=ip.getHostAddress();  

     }  

     }  

     }  

     } catch (SocketException e) {  

     e.printStackTrace();  

     }  

     if(netip!=null && !"".equals(netip)){  

     return netip;  

     }else{  

     return localip;  

     }  

    }

相關文章
相關標籤/搜索