这几天完全被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;
}
}