本人所有文章,只属学习整理及个人理解!有误还望谅解并指出,谢谢!持续更新中…
概述
TCP通信能实现两台计算机之间的数据交互,通信的两端,要严格区分为客户端(Client)与服务器(Server)。
两端通信时步骤:
1、服务端程序,需要事先启动,等待客户端的连接
2、客户端主动连接服务器端,连接成功才能通信。服务端不可以主动连接客户端。
再Java中,提供了两个类用于实现TCP通信程序:
1、客户端:java.net.Socket 类表示。创建 Socket 对象,向服务端发出连接请求,服务端响应请求,两者建立连接开始通信。
2、服务端:java.net.ServerSocket 类表示。创建 ServerSocket 对象。相当于开启一个服务,并等待客户端的连接。
Socket 类:该类实现客户端套接字,套接字指的是两台设备之间通讯的端点。
客户端往服务端发送【字节数据】案例:
/* 客户端代码 */
public static void main(String[] args) {
Socket socket = null;
OutputStream outputStream = null;
try {
socket = new Socket(InetAddress.getByName("localhost").getHostAddress(),9999);
outputStream = socket.getOutputStream();
outputStream.write("你好服务器".getBytes());
} catch (IOException e) {
e.printStackTrace();
} finally {
System.out.println("执行关闭流的代码");
try {
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
/* 服务端代码 */
public static void main(String[] args) {
InputStream inputStream = null;
try {
// 服务器
ServerSocket serverSocket = new ServerSocket(9999);
// 获取 socket
Socket socket = serverSocket.accept();
inputStream = socket.getInputStream();
byte[] buf = new byte[1024];
inputStream.read(buf);
String requestStr = new String(buf);
System.out.println("服务器:"+requestStr);
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
} finally {
System.out.println("执行关闭流的代码");
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
客户端往服务端发送【二进流数据】案例:
- 推荐使用
/* 客户端代码 */
public static void main(String[] args) {
DataOutputStream dataOutputStream = null;
try {
Socket socket = new Socket(InetAddress.getByName("localhost").getHostAddress(),9999);
dataOutputStream = new DataOutputStream(socket.getOutputStream());
dataOutputStream.writeUTF("你好服务器");
} catch (IOException e) {
e.printStackTrace();
} finally {
System.out.println("执行关闭流的代码");
try {
dataOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
/* 服务端代码 */
public static void main(String[] args) {
DataInputStream dataInputStream = null;
try {
// 服务器
ServerSocket serverSocket = new ServerSocket(9999);
// 获取 socket
Socket socket = serverSocket.accept();
// 创建二进制输入流
dataInputStream = new DataInputStream(socket.getInputStream());
// 获取客户端发送过来的数据
String msg = dataInputStream.readUTF();
System.out.println("服务器:"+ msg);
} catch (IOException e) {
e.printStackTrace();
} finally {
System.out.println("执行关闭流的代码");
try {
dataInputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
客户端往服务端发送【序列化数据】案例:
- 优点 可以将数据直接放入到对象当中;
- 缺点 如果在两个不同的工程之间,建立相同的序列化对象,连包名都必须一样,据了解这个缺点也和Dubbo被废弃有关系;
/* 实现了序列化 对象 */
public class Message implements Serializable {
private static final long serialVersionUID = -7263438503586272024L;
private String msg;
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
}
/* 客户端代码 */
public static void main(String[] args) {
ObjectOutputStream objectOutputStream = null;
try {
Socket socket = new Socket(InetAddress.getByName("localhost").getHostAddress(),9999);
objectOutputStream = new ObjectOutputStream(socket.getOutputStream());
Message message = new Message();
message.setMsg("你好服务器");
objectOutputStream.writeObject(message);
} catch (IOException e) {
e.printStackTrace();
} finally {
System.out.println("执行关闭流的代码");
try {
objectOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
/* 服务端代码 */
public static void main(String[] args) {
ObjectInputStream objectInputStream = null;
try {
// 服务器
ServerSocket server = new ServerSocket(9999);
// 获取客户端Socket
Socket socket = server.accept();
// 接受
objectInputStream = new ObjectInputStream(socket.getInputStream());
// 获取客户端发送过来的数据
Object object = objectInputStream.readObject();
if (object instanceof Message) {
Message message = (Message) object;
System.out.println("服务器:"+ message.getMsg());
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
System.out.println("执行关闭流的代码");
try {
objectInputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
服务端 无间断监听 客户端发送的消息 案例:
/* 客户端代码 */
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
while (true) {
Socket socket = null;
try {
socket = new Socket(InetAddress.getByName("localhost"),9999);
DataOutputStream dataOutputStream = new DataOutputStream(socket.getOutputStream());
dataOutputStream.writeUTF(scanner.nextLine());
DataInputStream dataInputStream = new DataInputStream(socket.getInputStream());
// 获取客户端发送过来的数据
String msg = dataInputStream.readUTF();
System.out.println("客户端:"+ msg);
} catch (IOException e) {
e.printStackTrace();
} finally {
System.out.println("执行关闭流的代码");
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
/* 服务端代码 */
public static void main(String[] args) {
Socket socket = null;
try {
// 服务器
ServerSocket serverSocket = new ServerSocket(9999);
while (true) {
// 获取 socket
socket = serverSocket.accept();
// 创建二进制输入流
DataInputStream dataInputStream = new DataInputStream(socket.getInputStream());
// 获取客户端发送过来的数据
String msg = dataInputStream.readUTF();
System.out.println("服务器:"+ msg);
DataOutputStream dataOutputStream = new DataOutputStream(socket.getOutputStream());
dataOutputStream.writeUTF(msg);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
System.out.println("执行关闭流的代码");
try {
socket .close();
} catch (IOException e) {
e.printStackTrace();
}
}
}