一、TCP 和 UDP
1.两个非常重要的运输层协议
- 传输控制协议TCP(Transmission Control Protocol)
- 用户数据报协议UDP(User Datagram Protocol)
传输控制协议TCP是面向连接的运输层协议。即应用进程(或程序)在使用TCP协议之前,必须先建立TCP连接,在传输完毕后,释放已经建立的连接。利用TCP协议进行通信的两个应用进程,一个是服务器进程。另一个是客户进程。
用户数据报协议UDP是面向无连接的运输层协议。即应用进程(或程序)在使用UDP协议之前,不必先建立连接。自然,发送数据结束时也没有连接需要释放。因此,减少了开销和发送数据之前的时延。
2.InetAdress类
Internet上的主机有两种方式表示地址:
- 域名:www.baidu.com
- IP 地址:123.125.114.114
InetAddress 类对象含有一个 Internet 主机地址的域名和IP地址:www.baidu.com/123.125.114.114
获取Internet上主机的地址:使用InetAddress类的静态方法:
getByName(String s):将一个域名或 IP 地址传递给该方法的参数,获得一个 InetAddress对象,该对象含有主机地址的域名和IP地 址,该对象用如下格式表示它包含的信息:www.baidu.com/123.125.114.114
3.IP和端口号
IP 地址标识 Internet 上的计算机,端口号标识正在计算机上运行的进程(程序)。
端口号与IP地址的组合得出一个网络套接字。
端口号被规定为一个 16 位的整数 0~65535。其中,0~1023被预先定义的服务通信占用(如telnet占用端口23,http占用端口80等)。除非我们需要访问这些特定服务,否则,就应该使用 1024~65535 这些端口中的某一个进行通信,以免发生端口冲突。
二、TCP网络编程
两个Java应用程序可通过一个双向的网络通信连接实现数据交换,这个双向链路的一段称为一个Socket (套接字)。Socket通常用来实现Client/Server 连接。
Java语言的基于套接字编程分为服务器编程和客户端编程,其通信模型如图所示:
1.基于Socket的程序
客户端Socket的工作过程包含以下四个基本的步骤:
- 创建 Socket。根据指定的 IP 地址或端口号构造 Socket 类对象。如服务器端响应,则建立客户端到服务器的通信线路。
- 打开连接到 Socket 的输入/出流。 使用 getInputStream()方法获得输入流,使用 getOutputStream()方法获得输出流。
- 按照一定的协议对 Socket 进行读/写操作。通过输入流读取服务器放入线路的信息(但不能读取自己放入线路的信息),通过输出流将信息写入线程。
- 关闭 Socket。断开客户端到服务器的连接,释放线路
服务器程序的工作过程包含以下四个基本的步骤:
- 对于服务器和客户机而言,将上述第一步改为构造 ServerSocket 类对象,监听客户端的请求并进行响应。
- 调用 ServerSocket(int port) 创建一个服务器端套接字,并绑定到指定端口上。
- 调用 accept(),监听连接请求,如果客户端请求连接,则接受连接,返回通信套接字。
- 调用 Socket类的 getOutputStream 和 getInputStream 获取输出流和输入流,开始网络数据的发送和接收。
- 最后关闭通信套接字。
2.服务器建立ServerSocket对象
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
/**
*
* 创建ServerSocket对象
*/
public class ServerSocketTest {
public static void main(String[] args) {
ServerSocket serverSocket = null;//申明
try {
serverSocket = new ServerSocket(8090);// ip 127.0.0.1
System.out.println("服务器开始监听....");
while(true){
Socket socket = serverSocket.accept();//开始监听指定的端口
System.out.println("接收到请求....");
//获取输入流
InputStream in = socket.getInputStream();
//获取输出流
OutputStream out = socket.getOutputStream();
//输出数据
out.write("恭喜你,你已经连接到服务器了!".getBytes());
out.flush();
//读取客户端的数据
byte [] buff = new byte [1024];
int len = in.read(buff);
String str = new String(buff,0,len);
System.out.println("服务器端>>>接收到客户端的数据为:"+str);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
3.客户端创建Socket对象
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
/**
*
* 创建socket对象
*/
public class SocketTest {
public static void main(String[] args) {
byte [] ip = {127,0,0,1};
Socket socket = null;
try {
socket = new Socket(InetAddress.getByAddress(ip), 8090);//连接服务器
OutputStream out = socket.getOutputStream();//获取输出流
InputStream in = socket.getInputStream();//获取输入流
//读取服务器短的数据
byte [] buff = new byte[1024];
int len = in.read(buff);
String serverInfo = new String(buff,0,len);
System.out.println("客户端>>>读取到服务器端的数据为:"+serverInfo);
//向服务器端输出数据
out.write("你好!".getBytes());
out.flush();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
三、UDP编程
类 DatagramSocket 和 DatagramPacket 实现了基于 UDP 协议网络程序。DatagramPacket 对象封装了UDP数据报,在数据报中包含了客户端的IP地址和端口号以及服务器的IP地址和端口号。
UDP数据报通过数据报套接字 DatagramSocket 发送和接收,系统不保证UDP数据报一定能够安全送到目的地,也不能确定什么时候可以抵达。