-------android培训、java培训、期待与您交流! ----------
TCP、UDP协议简介绍:
TCP是Tranfer Control Protocol的简称,是一种面向连接的保证可靠传输的协议。通过TCP协议传输,得到的是一个顺序的无差错的数据流。发送方和接收方的成对的两个socket之间必须建立连接,以便在TCP协议的基础上进行通信,当一个socket(通常都是server socket)等待建立连接时,另一个socket可以要求进行连接,一旦这两socket连接起来,它们就可以进行双向数据传输,双方都可以进行发送或接收操作。
UDP是User Datagram Protocol的简称,是一种无连接的协议,每个数据报都是一个独立的信息,包括完整的源地址或目的地址,它在网络上以任何可能的路径传往目的地,因此能否到达目的地,到达目的地的时间以及内容的正确性都是不能被保证的。
下面对这两种协议做简单比较:
使用UDP时,每个数据报中都给出了完整的地址信息,因此无需要建立发送方和接收方的连接。对于TCP协议,由于它是一个面向连接的协议,在socket之间进行数据传输之前必然要建立连接,所以在TCP中多了一个连接建立的时间。使用UDP传输数据时是有大小限制的,每个被传输的数据报必须限定在64KB之内。而TCP没有这方面的限制,一
旦连接建立起来,双方的socket就可以按统一的格式传输大量的数据。UDP是一个不可靠的协议,发送方所发送的数据报并不一定以相同的次序到达接收方。而TCP是一个可靠的协议,它确保接收方完全正确地获取发送方所发送的全数据。
小结:
TCP,可靠,传输大小无限制,但是需要连接建立时间,差错控制开销大。
UDP,不可靠,差错控制开销较小,传输大小限制在64K以下,不需要建立连接。
基于TCP/IP的网络编程:
java在包java.net中提供了两个类Socket和ServerSocket,分别用来表示双向连接的客户端和服务端。例如:
客户端:Socket client = new Socket("127.0.01.", 80);
服务端:ServerSocket server = new ServerSocket(80);
下面给出一个用Socket实现的客户和服务器交互的演示程序。
1. 客户端程序
import java.io.*;
import java.net.*;
public class TalkClient {
public static void main(String args[]) {
try{
Socket socket=new Socket("127.0.0.1",4700); //向本机的4700端口发出客户请求
BufferedReader sin=new BufferedReader(new InputStreamReader(System.in)); //由系统标准输入设备构造BufferedReader对象
PrintWriter os=new PrintWriter(socket.getOutputStream()); //由Socket对象得到输出流,并构造PrintWriter对象
BufferedReader is=new BufferedReader(new InputStreamReader(socket.getInputStream()));//由Socket对象得到输入流,并构造相应的BufferedReader对象
String readline;
readline=sin.readLine(); //从系统标准输入读入一字符串
while(!readline.equals("bye")){ //若从标准输入读入的字符串为 "bye"则停止循环
os.println(readline);//将从系统标准输入读入的字符串输出到Server
os.flush(); //刷新输出流,使Server马上收到该字符串
System.out.println("Client:"+readline); //在系统标准输出上打印读入的字符串
System.out.println("Server:"+is.readLine()); //从Server读入一字符串,并打印到标准输出上
readline=sin.readLine(); //从系统标准输入读入一字符串
} //继续循环
os.close(); //关闭Socket输出流
is.close(); //关闭Socket输入流
socket.close(); //关闭Socket
}catch(Exception e) {
System.out.println("Error"+e); //出错,则打印出错信息
}
}
}
2. 服务器端程序
import java.io.*;
import java.net.*;
import java.applet.Applet;
public class TalkServer{
public static void main(String args[]) {
try{
ServerSocket server=null;
try{
server=new ServerSocket(4700); //创建一个ServerSocket在端口4700监听客户请求
}catch(Exception e) {
System.out.println("can not listen to:"+e); //出错,打印出错信息
}
Socket socket=null;
try{
socket=server.accept(); //使用accept()阻塞等待客户请求,有客户
}catch(Exception e) {
System.out.println("Error."+e); //出错,打印出错信息
}
String line;
BufferedReader is=new BufferedReader(new InputStreamReader(socket.getInputStream()));//由Socket对象得到输入流,并构造相应的BufferedReader对象
PrintWriter os=newPrintWriter(socket.getOutputStream());//由Socket对象得到输出流,并构造PrintWriter对象
BufferedReader sin=new BufferedReader(new InputStreamReader(System.in));//由系统标准输入设备构造BufferedReader对象
System.out.println("Client:"+is.readLine()); //在标准输出上打印从客户端读入的字符串
line=sin.readLine(); //从标准输入读入一字符串
while(!line.equals("bye")){
os.println(line); //向客户端输出该字符串
os.flush(); //刷新输出流,使Client马上收到该字符串
System.out.println("Server:"+line); //在系统标准输出上打印读入的字符串
System.out.println("Client:"+is.readLine()); //从Client读入一字符串,并打印到标准输出上
line=sin.readLine(); //从系统标准输入读入一字符串
} //继续循环
os.close(); //关闭Socket输出流
is.close(); //关闭Socket输入流
socket.close(); //关闭Socket
server.close(); //关闭ServerSocket
}catch(Exception e){
System.out.println("Error:"+e); //出错,打印出错信息
}
}
}
利用多线程实现多客户机制实现在服务器方给 多个客户 提供服务的功能,对上面的程序进行改造如下:
ServerSocket serverSocket=null;
boolean listening=true;
try{
serverSocket=new ServerSocket(4700); //创建一个ServerSocket在端口4700监听客户请求
}catch(IOException e) { }
while(listening){ //永远循环监听
new ServerThread(serverSocket.accept(),clientnum).start();//监听到客户请求,根据得到的Socket对象和客户计数创建服务线程,并启动之
clientnum++; //增加客户计数
}
serverSocket.close(); //关闭ServerSocket
//设计ServerThread类
public class ServerThread extends Thread{
Socket socket=null; //保存与本线程相关的Socket对象
int clientnum; //保存本进程的客户计数
public ServerThread(Socket socket,int num) { //构造函数
this.socket=socket; //初始化socket变量
clientnum=num+1; //初始化clientnum变量
}
public void run() { //线程主体
try{
//在这里实现数据的接受和发送
}
}
}
包java.net中提供了两个类DatagramSocket和DatagramPacket用来支持数据报通信,DatagramSocket用于在程序之间建立传送数据报的通信连接, DatagramPacket则用来表示一个数据报。用数据报方式编写client/server程序时,无论在客户方还是服务方,首先都要建立一个DatagramSocket对象,用来接收或发送数据报,然后使用DatagramPacket类对象作为传输数据的载体。下面看一下DatagramPacket的构造方法 :
DatagramPacket(byte buf[],int length);
DatagramPacket(byte buf[], int length, InetAddress addr, int port);
DatagramPacket(byte[] buf, int offset, int length);
DatagramPacket(byte[] buf, int offset, int length, InetAddress address, int port);
其中,buf中存放数据报数据,length为数据报中数据的长度,addr和port旨明目的地址,offset指明了数据报的位移量。
在接收数据前,应该采用上面的第一种方法生成一个DatagramPacket对象,给出接收数据的缓冲区及其长度。然后调用DatagramSocket 的方法receive()等待数据报的到来,receive()将一直等待,直到收到一个数据报为止。
DatagramPacket packet=new DatagramPacket(buf, 256);
Socket.receive (packet);
发送数据前,也要先生成一个新的DatagramPacket对象,这时要使用上面的第二种构造方法,在给出存放发送数据的缓冲区的同时,还要给出完整的目的地址,包括IP地址和端口号。发送数据是通过DatagramSocket的方法send()实现的,send()根据数据报的目的地址来寻径,以传递数据报。
DatagramPacket packet=new DatagramPacket(buf, length, address, port);
Socket.send(packet);
基于URL网络编程:
URL(Uniform Resource Locator)是一致资源定位器的简称,它表示Internet上某一资源的地址。通过URL我们可以访问Internet上的各种网络资源,比如最常见的WWW,FTP站点。浏览器通过解析给定的URL可以在网络上查找相应的文件或其他资源。URL有以下及部分组成,协议名://机器名+端口号+文件名,协议名指明获取资源所使用的传输协议,如http、ftp、gopher、file等
为了表示URL, java.net中实现了类URL。我们可以通过下面的构造方法来初始化一个URL对象:
(1) public URL (String spec);通过一个表示URL地址的字符串可以构造一个URL对象。
URL url=new URL("http://www. baidu.com/")
(2) public URL(URL context, String spec); 通过基URL和相对URL构造一个URL对象。
URL url=new URL(new URL("http://www. baidu.com/"), "index.html")
(3) public URL(String protocol, String host, String file);
new URL("http", "www.XXX.com", "/index.php");
(4) public URL(String protocol, String host, int port, String file);
URL gamelan=new URL("http", "www.XXX.com", 80, "/index.php");
当我们得到一个URL对象后,就可以通过它读取指定的WWW资源。这时我们将使用URL的方法openStream(),方法openSteam()与指定的URL建立连接并返回InputStream类的对象以从这一连接中读取数据。代码如下:
public class URLReader {
public static void main(String[] args) throws Exception {
//声明抛出所有例外
URL tirc = new URL("http://www.XXX.com/");
//构建一URL对象
BufferedReader in = new BufferedReader(new InputStreamReader(tirc.openStream())); //使用openStream得到一输入流并由此构造一个BufferedReader对象
String inputLine;
while ((inputLine = in.readLine()) != null) //从输入流不断的读数据,直到读完为止
System.out.println(inputLine); //把读入的数据打印到屏幕上
in.close(); //关闭输入流
}
}
通过URL的方法openStream(),我们只能从网络上读取数据,如果我们同时还想输出数据,例如向服务器端发送一些数据,我们必须先与URL建立连接,然后才能对其进行读写,这时就要用到类URLConnection了。
类URLConnection也在包java.net中定义,它表示Java程序和URL在网络上的通信连接。当与一个URL建立连接时,首先要在一个URL对象上通过方法openConnection()生成对应的URLConnection对象。类URLConnection提供了很多方法来设置或获取连接参数,程序设计时最常使用的是getInputStream()和getOurputStream(),其定义为:
InputSteram getInputSteram();
OutputSteram getOutputStream();
通过返回的输入/输出流我们可以与远程对象进行通信。代码如下:
URL url =new URL ("http://www.XXX.com"); //创建一URL对象
URLConnectin con=url.openConnection(); //由URL对象获取URLConnection对象
DataInputStream dis=new DataInputStream (con.getInputSteam()); //由URLConnection获取输入流,并构造DataInputStream对象
PrintStream ps=new PrintSteam(con.getOutupSteam());//由URLConnection获取输出流,并构造PrintStream对象
String line=dis.readLine(); //从服务器读入一行
ps.println("client…"); //向服务器写出字符串 "client…"
------- android培训、java培训、期待与您交流! ---------- 详细请查看:http://edu.csdn.net/heima/