Android支持jdk本身的tcp、udp网络通信的api,也可以使用ServerSocket(服务器套接字)和Socket(套接字)建立基于Tcp/Ip网络协议的通信,也可以使用DatagramSocke、Datagrampacket、MulticastSocket建立基于UDP协议的网络通信
1. Tcp/Ip:
Tcp/Ip协议是网络通讯协议,Tcp和Ip是两个不同的协议,Ip协议(全称Internet Protocol即Interent协议)实现了端到端的查找(通过ip找到指定的计算机),通过ip协议实现了不同类型不同操作系统的计算机的连接,ip协议只保证计算机能接收和发送分组数据,负责将消息从一个主机传递到另一个主机,Ip不能解决数据分组在传输过程中可能出现的问题(例如主机down机,系统问题,网络连接中断等),造成数据的丢失或损坏。则还需要Tcp协议来提供可靠并且无差错的通信服务。Tcp协议是一种端对端的协议,当一台计算机需要与另一台计算机远程连接时,Tcp协议会让他们建立一个连接(虚拟链路)——用于发送和接收数据的虚拟链路。Tcp协议负责收集信息包,并保证数据包在传送中准确无误。Java使用Socket对象代表两端的通讯接口,并通过socket产生IO流进行网络通讯,综上只要连接到Internet的计算机都必须同时安装Tcp和Ip这两个协议,计算机之间再通过Socket进行连接监听、IO传递数据等。
Tcp通过ip实现端对端的查找,在通过tcp协议的Socket建立虚拟链路,进行网络通讯。
TCP/Ip协议簇包含了TCP/Ip协议层次模型,协议共分为4层:应用层、传输层、网络层、数据链路层。TCP/Ip协议是Internet使用的事实标准。
应用层是用户所面向的应用程序的统称,TCP/Ip协议簇在这一层有很多协议来支持不同的应用,Internet应用的实现离不开这些网络上的协议。如进行万维网(www)访问的就是http协议,文件传输用FTP协议,电子邮件发送用SMTP,域名解析用DNS协议,远程登录用Telnet协议等,都属于应用层。
传输层是提供应用程序的通信,TCP/Ip协议簇在这一层的协议有TCP和UDP协议。
网络层是TCp/Ip协议簇中的非常关键的一层,主要定义了IP地址格式,从而能够使得不同应用类型的数据在Internet上传输,IP协议就是一个网络层协议。
数据链路层是TCP/Ip软件的最底层,负责接收IP数据包并通过网络发送之,或从网络上几首物理帧,抽出IP数据报,交给IP层。
Ip协议又称互联网协议,是支持互联网间互联的数据报协议,它与TCP协议(传输控制协议)一起构成了TCP/Ip洗衣簇的核心。它提供网间连接的完善功能,包括IP数据包规定互联网范围内的IP地址格式。在互联网上,为了实现连接到网上的节点之间的通信,必须为每个节点(入网计算机)分配一个地址,并且应当保证这个地址是全网唯一的,这便是IP地址。
2. 端口:
一个主机可以与服务器上的多个进程保持Tcp连接,如一个主机既可以访问服务器的Web服务,又可以同时使用FTP服务下载文件,这就建立了两个连接,那如何区分是与服务器的那个进程连接的,就有了端口的概念,端口并不是真实物理存在的,而是一个假象的连接器。每个端口对应一个应用,这就识别了不同的进程,使主机同时连接了服务器的服务。
Tcp协议通过Socket套接字根据端口和ip协议建立两个主机之间的连接
80端口代表http连接网络服务,21端口号代表FTP服务
端口号的最大值是65535,在1024之前是well-know端口号
3. 客户端/服务器端通信模型
C/S(Client/Server)模型就是客户端/服务器通信模型,分为客户端程序和服务器端程序,通信是客户端向服务器端发送请求,服务器端接收到请求后返回数据到客户端,在Tcp通讯中两个通讯实体之间没有客户端和服务器端之分,只是在通讯实体没有建立虚拟链路之前,一个通讯实体作出了主动姿态,主动接受其他通讯实体的连接请求,就将其规定为服务器端,当客户端和服务器端建立连接后,则客户端和服务器端就成了相对的概念。只要是发出请求的都是客户端,此时相对的就是服务器端。
4. 套接字:
在java api中将套接字抽象化成类,程序可以通过Socket对象建立连接通过数据流进行网络通讯,使用Socket创建的程序就是Tcp程序。
ServerSocket就是主动接受其他通讯实体的连接请求的服务器套接字,服务器的套接字一次只可以与一个客户端的套接字连接,若有多个主机同时要求连接服务器,服务器套接字会将请求的客户端套接字存入队列中,一个一个的取出进行连接。队列默认大小是50,即一个服务器套接字可以同时接受50个连接请求。
方法:
Public ServerSocket(int port);指定使用的端口创建服务器套接字。
Public SetvertSocket(int port,int backlog); 指定使用的端口创建服务器套接字。Backlog是队列大小,端口则绑定了该服务,客户端凭借这个找到该服务器套接字,即找到该服务。
Public SetvertSocket(int port,int backlog,InetAddressbindAddr);指定使用的端口创建服务器套接字。Backlog是队列大小,bindAddr是绑定的ip的信息。InetAddress能够获取ip的相关信息
Public Socket accept();等待客户机请求,若连接则创建一个套接字并返回。
Public voidclose();关闭服务器的套接字。
Public Boolean isClose();若服务器套接字成功关闭则返回true
Public InetAddress getInetAddress();返回与服务器结合的ip的相关信息的类
Public voidbind(SocketAddress endpoint);绑定与endpoint对应的套接字地址(IP地址+端口号)
Public Boolean isBound();若服务器套接字已经与某个套接字绑定了则返回true
套接字:
Socket就是套接字类,必须指定连接的服务器ip及端口号,只有这样才能连接到服务器套接字,从而进行通讯。客户端创建套接字后,将马上向指定的ip发起连接请求。服务器套接字创建套接字对象进行连接,之后就可以通讯了。
方法
Public Socket(Stringsort,int port);创建指定ip和端口号的套接字
Public Socket(InetAddressaddress,int port);创建指定IP地址信息和端口号的套接字
Public InetAddress getInetAddress();获取被连接的服务器的ip信息的类
Public intgetPort();//获取端口号
Public InetAddress getLocalInetAddress();获取本地的ip地址信息的类
Public int getLocalPort();//获取本地端口号
Public Inputstream getInputStream();获取套接字的输入流
Public outputStream getOutputStream();获取套接字的输出流
基于稳定协议Tcp协议的socket通信:
可用于聊天的实现。这是c/s:客户端和服务器端的模型。
(1) 服务器端
调用ServerSocket(int port)创建服务器套接字
调用accept()监听连接。连接成功返回套接字,若没有人连接则会一直处于等待状态。
调用套接字的getInputStream()和getOutputStream()获取输出和输入流
关闭通讯流套接字
(2) 客户端
调用Socket(),创建套接字
调用套接字的getInputStream()和getOutputStream()获取输出和输入流
关闭通讯流套接字
使用例子
public classSimpleServer {
public static void main(String[] args) {
try {
ServerSocketserverSocket=new ServerSocket(3000);
while(true){
Socketsocket=serverSocket.accept();
OutputStreamstreame=socket.getOutputStream();
PrintStreamstreams=new PrintStream(streame);//包装流,打印流
streams.print("接收到来自服务器的通知,/n");//可以打印任意的数据类型。
streame.close();
streams.close();
socket.close();
}
}catch(IOExceptione) {
e.printStackTrace();
}
}
}
public classMySocket {
public static void main(String[] args) {
new Thread(newRunnable() {
@Override
public void run() {
try {
Socketsocket=new Socket("127.0.0.1",3000);//第一主机地址,第二个是主机的端口号
InputStreamstream=socket.getInputStream();
BufferedReaderreader=new BufferedReader(new InputStreamReader(stream));
Stringlinge=reader.readLine();
System.out.println(linge);
reader.close();
socket.close();
}catch(UnknownHostExceptione) {
e.printStackTrace();
}catch(IOExceptione) {
e.printStackTrace();
}
}
}).start();
}
}
多服务器连接的
将服务器写成多线程的,不同的处理线程为不同的客户服务,主线程只负责循环等待,处理线程负责网络连接,接收客户输入的信息,在服务器的程序中首先创建单个ServerSocket,并调用accept()来等候一个新连接,一旦accept()返回,就取得获得结果的Socket,并用它新建一个线程,令其只为那个特定的客户提供服务。然后再调用accept(),等候下一个新的连接请求。
boolean listening=true;
serverSocket = new ServerSocket(4444);
while (listening){
Socket socket;
socket = serverSocket.accept(); //程序将在此等候客户端的连接
Thread t = new MultiTalkServerThread(socket);
t.start( );//为新客户建立一条新的线程,并运行
}
serverSocket.close();
class MultiTalkServerThread extends Thread
{
private socket;
public MultiTalkServerThread(Socket socket)
{
this.socket = socket;
}
public void run()
{
…//处理用户需求
}
}
还要添加Internet权限
UDP协议:
UDP(User Datagram protoccol)协议洗衣称为用户数据报协议,该协议不需要事先建立连接就可以进行通讯,这样减少了连接的耗时,传输数据是异步的使数据及时发送到网络上,但这样容易造成数据的丢失和损坏,所以其对于传输数据是不可靠的,采用UDP协议通信的双方都可以称为服务器端。UdP多用于发送和返回的数据较短情况下
Tcp与udp的比较:Tcp协议是先建立连接在进行通信,Tcp使用了重发机制:当一个通信实体发送消息该另一个通信实体后需要收到另一个通信实体的确认信息,如果没有收到另一个通信实体的确认信息则会重新发送刚才的消息,保证了数据的准确性。
UDP程序设计:
(1) 接收端程序
调用DatagramSocket(int port)创建数据报套接字
调用DatagramPacket(byte[] buf,int length),建立字节数据已接收UDP包
调用DatagramSocket的receive(),接收UDP包
关闭数据套接字
(2) 发送程序端
调用DatagramSocket()创建一个数据包套接字
调用DatagramPacket(byte[] buf,int offset,int length,InetAddress addrss,intport);建立发送的UDP包
调用DatagramSocket 的send(),发送UDP包
关闭数据包套接字