- 使用TCP编程实现客户端到客户端的群聊通信
学习内容:
- 使用多线程技术实现通信;
- 复习java网络编程;
- 尝试使用idea远程连接服务器进行远程开发;
- 尝试在Linux的服务器环境进行;
学习时间:
- 2022/4/30 10:00 - 14:25
学习过程:
- 简单写一下大体过程
- 服务端:
package test01;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.concurrent.CopyOnWriteArrayList;
public class Server {
public static void main(String[] args){
ServerSocket serverSocket = null;
CopyOnWriteArrayList clients = new CopyOnWriteArrayList<>();
// ArrayList clients = new ArrayList<>();
try {
serverSocket = new ServerSocket(8989);
} catch (IOException e) {
System.out.println("端口不可用");
e.printStackTrace();
}
System.out.println("服务区启动成功,等待客户端连接....");
try {
while (true) {
//等待客户端
Socket socket = serverSocket.accept();
String ip = socket.getInetAddress().toString();
String port = socket.getPort()+"";
clients.add(socket);
System.out.println("客户端 ip:"+ip+"+port:"+port+" 连接成功!");
//不停地接收和发送消息(启动一个线程去监听这个客户端)
ServerDealThread sdt = new ServerDealThread(clients,socket);
sdt.start();
}
}catch (Exception e){
e.printStackTrace();
}
}
}
- 其余的工具类、线程类:
- 包括:收发消息工具类、释放资源工具类(没有完全用上,姑且先随便写写)、客户端的收发线程、服务端处理消息线程
package test01;
import java.io.*;
import java.net.Socket;
public class SRUtil {
public static void send(Socket socket, String msg){
OutputStream os = null;
BufferedWriter bw = null;
try {
os = socket.getOutputStream();
bw = new BufferedWriter(new OutputStreamWriter(os));
bw.write(msg);
bw.newLine();
bw.flush();
}catch (Exception e){
e.printStackTrace();
ReleaseUtil.release(socket,os);
}
}
public static String receive(Socket socket){
InputStream is = null;
BufferedReader br = null;
try{
is = socket.getInputStream();
br = new BufferedReader(new InputStreamReader(is));
String msg = br.readLine();
return msg;
}catch (Exception e){
e.printStackTrace();
ReleaseUtil.release(socket,is);
}return null;
}
}
package test01;
import java.io.Closeable;
import java.io.IOException;
import java.net.Socket;
public class ReleaseUtil {
public static void release(Socket socket, Closeable... targets){
for(Closeable target:targets){
if(null != target){
try {
target.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
package test01;
import java.net.Socket;
import java.util.Scanner;
public class SendThead extends Thread{
private Socket socket;
private Scanner sc = new Scanner(System.in);
public SendThead(Socket socket) {
this.socket = socket;
}
@Override
public void run() {
while(true){
String msg = sc.nextLine();
SRUtil.send(socket,msg);
//System.out.println("send!");
}
}
}
package test01;
import java.net.Socket;
public class ReceiveThread extends Thread{
private Socket socket ;
public ReceiveThread(Socket socket) {
this.socket = socket;
}
@Override
public void run() {
while(true){
String msg = SRUtil.receive(socket);
System.out.println(msg);
}
}
}
package test01;
import java.net.Socket;
import java.util.concurrent.CopyOnWriteArrayList;
public class ServerDealThread extends Thread{
public volatile boolean end = false;
private CopyOnWriteArrayList clients;
private Socket curCilent;
public ServerDealThread(CopyOnWriteArrayList clients, Socket curCilent) {
this.clients = clients;
this.curCilent = curCilent;
}
@Override
public void run() {
while (!end){
String msg = SRUtil.receive(curCilent);
System.out.println("Server: successfully got a msg...");
for (Socket tarCilent:clients) {
if (tarCilent.equals(curCilent)) continue;
SRUtil.send(tarCilent,msg);
}
System.out.println("Server: successfully send a msg to all...");
}
}
}



