這幾天徹底被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;
}
}