基于TCP协议的socket编程实现简单聊天室——客户端多线程
程序员文章站
2022-06-06 16:07:07
...
前言
使用循环解决多次聊天,使用线程解决先发后收的问题。
服务器端
服务器只用一个main方法,包含创建ServerSocket对象,监听客户端连接,使用DataInputStream获取客户端传输的数据,使用DataOutputStream发送到客户端反馈,循环保证长时间通信。
public static void main(String[] args) throws IOException {
System.out.println("------------------服务端开启-----------------------");
//创建ServerSocket对象
ServerSocket serverSocket = new ServerSocket(9999);
//监听是否有客户端连接
Socket client = serverSocket.accept();
//使用数据流
DataInputStream dataInputStream = new DataInputStream(client.getInputStream());
DataOutputStream dataOutputStream = new DataOutputStream(client.getOutputStream());
while (true){
String str = dataInputStream.readUTF();
System.out.println("客户端发送数据为" +str);
dataOutputStream.writeUTF("收到"+ str);
}
}
多线程发送
实现Runnable接口,我们的客户端使用BufferedReader读取字符流,使用DataOutputStream发送到服务器端。具体每行代码都有注释。
/**
* @author gaozhihao
* @date 2020/3/22 23:48
*/
public class Send implements Runnable{
//缓冲字符流
private BufferedReader bufferedReader ;
//发送给服务器的数据流
private DataOutputStream dataOutputStream ;
//如果线程失败,结束线程
private Boolean flag = true;
//初始化BufferedReader 从键盘输入
public Send(){
bufferedReader = new BufferedReader(new InputStreamReader(System.in));
}
//有参构造传入Socket,并初始化DataOutputStream
public Send(Socket socket){
//调用无参构造方法
this();
try {
dataOutputStream = new DataOutputStream(socket.getOutputStream());
} catch (IOException e) {
e.printStackTrace();
}
}
//读取数据
private String getMessage(){
String string = "";
try {
//键盘输入 复制给string
string = bufferedReader.readLine();
} catch (IOException e) {
flag = false;
CloseUtil.closeAll(bufferedReader);
}
return string;
}
//发送数据
private void send(String str){
try {
//发送给服务器端字符串
dataOutputStream.writeUTF(str);
//刷新
dataOutputStream.flush();
} catch (IOException e) {
flag = false;
CloseUtil.closeAll(dataOutputStream);
}
}
@Override
public void run() {
//当flag为true 发送键盘获取的数据
while (flag){
send(getMessage());
}
}
}
多线程接收
接收类和发送类是差不多的,主要是接收服务器端返回的数据流。
/**
* @author gaozhihao
* @date 2020/3/23 0:07
*/
public class Receive implements Runnable{
//接收数据流
private DataInputStream dataInputStream;
//
private Boolean flag = true;
//有参构造传入Socket对象,初始化DataInputStream
public Receive(Socket socket){
try {
dataInputStream = new DataInputStream(socket.getInputStream());
} catch (IOException e) {
if (dataInputStream != null){
flag = false;
CloseUtil.closeAll(dataInputStream);
}
}
}
//获取数据流中的数据
private String getMessage(){
String str = "";
try {
str = dataInputStream.readUTF();
} catch (IOException e) {
e.printStackTrace();
}
return str;
}
@Override
public void run() {
while (flag){
System.out.println(this.getMessage());
}
}
}
客户端
客户端代码简单,主要是创建socket对象,并启动线程。
public static void main(String[] args) throws IOException {
//使用InetAddress获取IP地址
InetAddress inetAddress = InetAddress.getLocalHost();
//创建socket对象
Socket client = new Socket( inetAddress.getHostAddress(),9999);
//启动发送和接收线程
new Thread(new Send(client)).start();
new Thread(new Receive(client)).start();
}
运行效果
最终实现单个客户端与服务器多次通信。
上一篇: RobotFrameWork导入库失败及中文乱码处理
下一篇: Java实现餐厅点餐系统的实例代码
推荐阅读
-
Java编程实现基于TCP协议的Socket聊天室示例
-
Java编程实现基于TCP协议的Socket聊天室示例
-
linux网络编程之用socket实现简单客户端和服务端的通信(基于TCP)
-
Python3学习(六):使用socket实现TCP协议的简单服务器和客户端
-
基于TCP协议的socket编程实现简单聊天室——客户端多线程
-
Day.55————C++ socket编程实现简单的UDP、TCP通信(服务端+客户端)
-
Socket TCP 协议实现服务端和客户端的简单通信
-
linux网络编程之用socket实现简单客户端和服务端的通信(基于UDP)
-
Linux Socket编程---TCP实现多客户端的网络聊天室
-
网络编程——socket @[TOC]( 基于tcp协议的收发聊天室