Java中的TCP协议:
TCP协议提供面向连接的服务,通过它建立的是可靠地连接。Java为TCP协议提供了两个类:Socket类和ServerSocket类。
一个Socket实例代表了TCP连接的一个客户端,而一个ServerSocket实例代表了TCP连接的一个服务器端,一般在TCP Socket编程中,客户端有多个,而服务器端只有一个,客户端TCP向服务器端TCP发送连接请求,服务器端的ServerSocket实例则监听来自客户端的TCP连接请求,并为每个请求创建新的Socket实例,由于服务端在调用accept()等待客户端的连接请求时会阻塞,直到收到客户端发送的连接请求才会继续往下执行代码,因此要为每个Socket连接开启一个线程。服务器端要同时处理ServerSocket实例和Socket实例,而客户端只需要使用Socket实例。另外,每个Socket实例会关联一个InputStream和OutputStream对象,我们通过将字节写入套接字的OutputStream来发送数据,并通过从InputStream来接收数据。
TCP连接的建立步骤:
客户端向服务器端发送连接请求后,就被动地等待服务器的响应。典型的TCP客户端要经过如下操作:
1、创建Socket连接服务端(指定ip地址,端口号)通过ip地址找对应的服务器,建立一个TCP连接;
2.通过Socket套接字的的getInputStream()和getOutputStream()方法获取和服务端相连的IO流。输入流可以读取服务端输出流写出的数据,输出流可以写出数据到服务端的输入流;
3、使用Socket类的close方法关闭连接。
服务端的工作是建立一个通信终端,并被动地等待客户端的连接。典型的TCP服务端执行如下操作:
1、创建一个ServerSocket实例并指定本地端口,用来监听客户端在该端口发送的TCP连接请求;
2、重复执行:
1)调用ServerSocket的accept()方法以获取客户端连接,并通过其返回值创建一个Socket实例;
2)为返回的Socket实例开启新的线程,并调用Socket的getInputStream()和getOutputStream()方法获取和客户端相连的IO流,输入流可以读取客户端输出流写出的数据,输出流可以写出数据到客户端的输入流;
3)通信完成后,使用Socket类的close()方法关闭该客户端的套接字连接。
TCP Socket Demo:
客户端代码如下:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintStream;
import java.net.Socket;
import java.net.UnknownHostException;
public class Demo_Client {
static void main(String[] args) throws UnknownHostException, IOException {
Socket socket = new Socket("127.0.0.1", 12345);
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));//将字节流包装成了字符流
PrintStream ps = new PrintStream(socket.getOutputStream());//PrintStream中有写出换行的方法
System.out.println(br.readLine());
ps.println("中国的首都在哪?");
System.out.println(br.readLine());
ps.println("知道了");
socket.close();
}
}
服务端代码如下:
public static void main(String[] args) throws IOException {
ServerSocket server = new ServerSocket(12345);
while(true) {//不断接受客户端的请求
final Socket socket = server.accept();
new Thread() {
public void run() {
try {
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));//将字节流包装成了字符流
PrintStream ps = new PrintStream(socket.getOutputStream()); //PrintStream中有写出换行的方法,所以用它
ps.println("百度一下,你就知道。");
System.out.println(br.readLine());
ps.println("北京");
System.out.println(br.readLine());
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}.start();
}
}