使用Java实现基于TCP协议的网络通信
TCP/IP通信协议是一种可靠的网络协议,它在通信的两端各建立一个Socket,从而在通信的两端之间形成网络虚拟链路。一旦建立了虚拟的网络链路,两端的程序就可以通过虚拟链路进行通信。Java对基于TCP协议的网络通信提供了良好的封装,Java使用Socket对象来代表两端的通信端口,并通过产生IO流来进行网络通信。
两个实体通信示意图:
Java中能接收其他通信实体连接请求的类是ServerSocket,ServerSocket对象用于监听来自客户端的Socket连接,如果没有连接,它将一直处于等待状态。ServerSocket包含一个监听来自客户端连接请求的方法。
-
Socket accept():如果接收到一个客户端Socket的连接请求,该方法讲返回一个客户端Socket对应的Socket;否则该方法将一直处于等待状态,线程也被阻塞。
创建ServerSocket对象,有以下几个构造器: -
ServerSocket(int port):用指定的端口port来创建一个对象。该端口应该有一个有效的端口值,在0-65535之间。
-
ServerSocket(int port,int backlog):增加一个用来改变连接队列长度的参数backlog。
-
ServerSocket(int port,int backlog,InetAddress localAddr):在机器存在多个IP地址的情况下,允许通过localAddr参数来指定将ServerSocket绑定到指定的IP地址。
使用Socket进行通信:
客户端通常可以使用Socket的构造器来连接到指定服务器,Socket通常使用如下两个构造器: -
Socket(InetAddress/String remoteAddress,int port):创建连接到指定远程主机、远程端口的Socket,并没有指定本地地址、本地端口,默认使用本地主机的默认IP地址,默认使用系统动态分配的端口。
-
Socket(InetAddress/String remoteAddress,int port,InetAddress localAddr,int localPort):创建连接到指定远程主机、远程端口的Socket,并指定本机IP地址和本地端口,适用于本地主机有多个IP地址的情形。
建立Server端:
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
public class TCPServer {
private int port = 12345;//定义端口号
private ServerSocket socket;//定义ServerSocket
public TCPServer() {//构造器:创建ServerSocket对象
try {
socket = new ServerSocket(port);
} catch (IOException e) {
e.printStackTrace();
}
}
//启动服务器类
public void startServer() {
try {
while (true) {
//让服务器一直监听是否有新的客户请求连接
Socket clientSocket = socket.accept();
//建立通信:获取字节流
InputStream inputStream = clientSocket.getInputStream();//输入流
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
OutputStream outputStream = clientSocket.getOutputStream();//输出流
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(outputStream));
while (true) {
String s = null;
s = reader.readLine();
System.out.println("收到的消息为:" + s);
if (s.equals("exit")) {
break;
}
//给客户端回复消息
String str = "I receive your msg\n";//加回车把消息刷新出缓冲区
writer.write(str);
writer.flush();
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
new TCPServer().startServer();
}
}
建立Client端:
import java.io.*;
import java.net.Socket;
import java.util.Scanner;
public class TCPClient {
private int port = 12345;//连接进程的端口号
private String IP = "127.0.0.1";//服务器的IP地址
private Socket clientSocket;
private Scanner scanner;
public TCPClient(){
try {
scanner = new Scanner(System.in);
clientSocket = new Socket(IP,port);//创建socket对象
} catch (IOException e) {
e.printStackTrace();
}
}
public void startClient(){
OutputStream outputStream = null;
BufferedWriter writer = null;
InputStream inputStream = null;
BufferedReader reader = null;
try {
outputStream = clientSocket.getOutputStream();
writer = new BufferedWriter(new OutputStreamWriter(outputStream));
inputStream = clientSocket.getInputStream();//输入流
reader = new BufferedReader(new InputStreamReader(inputStream));
while(true){
String s = scanner.nextLine();
writer.write(s);
writer.write("\n");
writer.flush();
//结束通信:客户端输入exit
if(s.equals("exit")){
break;
}
//就收服务端信息
String msg = reader.readLine();
System.out.println("收到服务器消息:"+msg);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
//关闭资源
try {
outputStream.close();
inputStream.close();
reader.close();
writer.close();
clientSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
TCPClient client = new TCPClient();
client.startClient();
}
}
应用多线程
新建一个ServerHandler类:(也就是将通信部分的代码用多线程的方式实现)
import java.io.*;
import java.net.Socket;
public class ServerHandler implements Runnable{
private Socket clientSocket;
public ServerHandler(Socket clientSocket){
this.clientSocket = clientSocket;
}
@Override
public void run() {
OutputStream outputStream = null;
InputStream inputStream = null;
BufferedReader reader = null;
BufferedWriter writer = null;
try {
//让服务器一直监听是否有新的客户请求连接
//建立通信:获取字节流
inputStream = clientSocket.getInputStream();//输入流
reader = new BufferedReader(new InputStreamReader(inputStream));
outputStream = clientSocket.getOutputStream();//输出流
writer = new BufferedWriter(new OutputStreamWriter(outputStream));
while (true) {
String s = null;
s = reader.readLine();
System.out.println("收到的消息为:" + s);
if (s.equals("exit")) {
break;
}
//给客户端回复消息
String str = "I receive your msg\n";//加回车把消息刷新出缓冲区
writer.write(str);
writer.flush();
}
} catch (IOException e) {
e.printStackTrace();
} finally {
//关闭资源
try {
outputStream.close();
inputStream.close();
reader.close();
writer.close();
clientSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
//Server端启动代码:在TCPServer中的代码
public void startServer() {
try {
while (true) {
//让服务器一直监听是否有新的客户请求连接
Socket clientSocket = socket.accept();
new Thread(new ServerHandler(clientSocket)).start();
}
} catch (IOException e) {
e.printStackTrace();
}
}
上一篇: 手机与PC革命性融合 华为“多屏协同”功能正式亮相
下一篇: 年羹尧死后被抄家,七个字气坏了雍正爷!