转:Android开发 socket

这几天完全被socket 卡住了, 主要原因就是就ip,Socket通信主要有俩种,1,TCP,2,UDP

一,什么时候SOCKET通信:

你经常听到人们谈论着 “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 应用程序的时候非常重要。

主要程序:

服务器端:TCP 

 

                        //创建一个ServerSocket对象,并让这个Socket在4567端口监听

serverSocket = new ServerSocket(4567);

//调用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;  

     }  

    }

posted @ 2012-05-29 16:10  xiaodao9527  阅读(121)  评论(0编辑  收藏  举报