目录
上一篇章当中已经介绍了UDP的使用,接下来详细介绍TCP的套接字,网络编程模块
ServerSocket介绍
ServerSocket是创建TCP服务端的Socket的api
构造方法
| 方法签名 | 方法说明 |
|---|---|
| ServerSocket(int port) | 创建一个服务端流套接字Socket,并绑定到指定端口 |
| Socket accept() | 监听指定端口,有客户端连接之后,返回一个服务端Socket对象,并基于该Socket建立与客户端的连接,否则阻塞等待 |
| void close() | 关闭套接字 |
Socket介绍
Socket是客户端的Socket,或服务端中接收到的客户端建立连接(accept方法)的请求后,返回的服务端Socket
用于保存对端信息,及时用于与对方进行收发数据的
构造方法
| 方法签名 | 方法说明 |
|---|---|
| Socket(String host,int port) | 创建一个客户端流套接字Socket,并于对应IP的主机上,对应端口的进程建立连接 |
| InetAddress getInetAddress() | 返回套接字所连接的地址 |
| InputStream getInputStream() | 返回套接字输入流 |
| OutputStream getOutputStream | 返回此套接字的输出流 |
代码示例
在此处实现的这个是一个回显服务器,就会发现与UDP的差别是非常大的,字节流使用,多次处理信息,保存对端信息
服务器:
java
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;
/**
* 服务端
*/
public class TcpEchoServer {
private ServerSocket serverSocket = null;//这个主要是对服务器使用的
// 1. 构造方法,绑定服务器这边的端口
public TcpEchoServer(int port) throws IOException {
serverSocket = new ServerSocket(port);
}
// 2. 程序启动
public void start() throws IOException {
System.out.println("服务器启动");
while (true){//服务端需要持续不断的处理请求
Socket clientSocket = serverSocket.accept();//先处理客户端发来的连接,如果没有发来链接,就会出现阻塞
processConnection(clientSocket);//对客户端发来的数据进行处理
}
}
public void processConnection(Socket clientSocket){
//接下来可以读取请求,根据请求计算响应,返回响应三步走
// Socket 对象内部包含了两个字节流对象,可以把这两字节流对象获取,完成后续读与写操作
// 因为再TCP当中是字节流的方式进行读取的
try (InputStream inputStream = clientSocket.getInputStream();
OutputStream outputStream = clientSocket.getOutputStream()){
// 一次连接,可能会涉及多次请求/响应
while (true){
// 1. 请求读取并进行解析
Scanner scanner = new Scanner(inputStream);
if(!scanner.hasNext()){
//读取完毕,客户端下线
System.out.println("客户端下线");
break;
}
// 使用next接收,就是有一个约定,客户端发来的请求,一定需要是文本数据
String request = scanner.next();
// 2. 根据请求计算相应
String response = process(request);
// 3. 把响应写给客户端, 把OutputStream使用PrinterWriter包裹
PrintWriter writer = new PrintWriter(outputStream);
//使用 PrintWriter的println方法,把响应返回给客户端
//此处的println,不是print就是为了在结尾上加上/n结束标志
writer.println(response);//此时相当于把内容放到了缓冲区上
//需要加一个刷新缓冲区的操作
writer.flush();
}
}catch (IOException e){
e.printStackTrace();
}finally {
//在此处加上关闭操作
try {
clientSocket.close();
}catch (IOException e){
e.printStackTrace();
}
}
}
public String process(String request){
return request;
}
public static void main(String[] args) throws IOException {
TcpEchoServer server = new TcpEchoServer(9090);
server.start();;
}
}
客户端:
java
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Scanner;
/**
* 客户端
*
*/
public class TcpEchoClient {
private Socket socket;
// 1. 构造方法
// 要和服务器通信,需要知道服务器所在的位置
public TcpEchoClient(String serverIp,int serverPort) throws IOException {
socket = new Socket(serverIp,serverPort);
}
// 正式请求
public void start() throws IOException {
System.out.println("客户端启动");
// 从控制台读取数据
Scanner scannerConsole = new Scanner(System.in);
try (InputStream inputStream = socket.getInputStream();
OutputStream outputStream = socket.getOutputStream()){
while (true){
// 1. 从控制台输入字符串
String request = scannerConsole.next();
// 2. 把请求发送给服务器
PrintWriter printWriter = new PrintWriter(outputStream);
printWriter.println(request);//作用就是为了进行换行
printWriter.flush();
// 3. 从服务器读取响应
Scanner scannerNetwork = new Scanner(inputStream);
String response = scannerNetwork.next();
//4. 把相应打印出来
System.out.println(response);
}
}catch (IOException e){
e.printStackTrace();
}finally {
socket.close();
}
}
public static void main(String[] args) throws IOException {
TcpEchoClient client = new TcpEchoClient("127.0.0.1",9090);
client.start();
}
}
上述的两种写法可以说是相差是非常大的差别的,还是需要进行练习!