通信软件的功能:有客户端和服务器端,实现客户端和服务器相互不停的发送和接收消息。要求发送和接收消息可以同时进行。
一、客户端与服务器交流
服务器
package zpb.practice;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.util.Scanner;
public class ServerTOClient extends Thread {
ServerSocket server = null;
Socket socket = null;
public ServerTOClient(int port) {
try {
server = new ServerSocket(port);
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
ServerTOClient server = new ServerTOClient(8888);
server.start();
}
@Override
public void run() {
super.run();
try {
System.out.println("等待连接...");
socket = server.accept();
new sendMessThread().start();
System.out.println(socket.getInetAddress().getHostAddress() + "连接成功!");
InputStream in = socket.getInputStream();
int len = 0;
byte[] buf = new byte[64];
try {
while ((len = in.read(buf)) != -1) {
System.out.println("客户端:" + new String(buf, 0, len));
}
} catch (SocketException s) {
System.out.println("服务器已关闭");
}
} catch (IOException e) {
e.printStackTrace();
}
}
class sendMessThread extends Thread {
@Override
public void run() {
super.run();
Scanner scanner = null;
OutputStream out = null;
try {
if (socket != null) {
scanner = new Scanner(System.in);
out = socket.getOutputStream();
String in = "";
while (!in.equals("关闭")) {
in = scanner.next();
out.write(("服务器:" + in).getBytes());
out.flush();
}
scanner.close();
out.close();
socket.close();
}
} catch (IOException e) {
System.out.println("客户端已关闭,你的信息无法传输了");
}
}
}
}
客户端
package zpb.practice;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.SocketException;
import java.util.Scanner;
public class ClientTOServer extends Thread {
Socket socket = null;
public ClientTOServer(String host, int port) {
try {
socket = new Socket(host, port);
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
ClientTOServer clientTest = new ClientTOServer("127.0.0.1", 8888);
clientTest.start();
}
@Override
public void run() {
new sendMessThread().start();
super.run();
try {
InputStream s = socket.getInputStream();
byte[] buf = new byte[64];
int len = 0;
try {
while ((len = s.read(buf)) != -1) {
System.out.println(new String(buf, 0, len));
}
} catch (SocketException so) {
System.out.println("客户端已关闭");
}
} catch (IOException e) {
e.printStackTrace();
}
}
class sendMessThread extends Thread {
@Override
public void run() {
super.run();
Scanner scanner = null;
OutputStream os = null;
try {
scanner = new Scanner(System.in);
os = socket.getOutputStream();
String in = "";
while (!in.equals("再见")) {
in = scanner.next();
os.write(("" + in).getBytes());
os.flush();
}
} catch (IOException e) {
System.out.println("服务器已关闭,你的信息无法传输了");
}
scanner.close();
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
代码的实现参考自此博客,十分感谢!
二、多个客户端与服务器群流
服务器
package zpb.practice;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashMap;
import java.util.Map;
public class ChatServer {
private static final int port = 8888;
private ServerSocket server_socket;
private Map<String, Socket> clients;
public ChatServer() throws IOException {
this.server_socket = new ServerSocket(port);
this.clients = new HashMap<>();
while (true) {
Socket client_socket = server_socket.accept();
new HandleClientThread(client_socket).start();
}
}
public static void main(String[] args) throws IOException {
new ChatServer();
}
private synchronized void showUserList() {
System.out.println("🐉🐉🐉🐉🐉用户列表🐉🐉🐉🐉🐉");
System.out.println("当前在线人数:" + clients.size());
for (Map.Entry<String, Socket> user : clients.entrySet()) {
System.out.println(user.getKey());
}
}
private synchronized void sendToAllClient(String message) {
try {
for (Map.Entry<String, Socket> user : clients.entrySet()) {
PrintWriter server_out = new PrintWriter(user.getValue().getOutputStream(), true);
server_out.println(message);
}
} catch (IOException e) {
e.printStackTrace();
}
}
private synchronized void sendToUser(String sendUser, String receiveUser, String message) {
try {
PrintWriter out = new PrintWriter(clients.get(receiveUser).getOutputStream(), true);
out.println(sendUser + "对你说:" + message);
} catch (IOException e) {
e.printStackTrace();
}
}
private synchronized void offline(String username) {
clients.remove(username);
if (username != null) {
sendToAllClient(username + "已下线!");
}
ChatServer.this.showUserList();
}
private class HandleClientThread extends Thread implements Runnable {
private Socket client_socket;
private BufferedReader server_in;
private PrintWriter server_out;
private String client_name;
public HandleClientThread(Socket client_socket) throws IOException {
this.client_socket = client_socket;
server_in = new BufferedReader(new InputStreamReader(this.client_socket.getInputStream()));
server_out = new PrintWriter(this.client_socket.getOutputStream(), true);
server_out.println("您已连接上聊天服务器!请输入用户名:");
}
@Override
public void run() {
int flag = 0;
String fromClientData;
try {
while ((fromClientData = server_in.readLine()) != null) {
if ("退出聊天".equals(fromClientData)) {
ChatServer.this.offline(this.client_name);
break;
}
if (flag++ == 0) {
this.client_name = fromClientData;
clients.put(this.client_name, this.client_socket);
sendToAllClient("欢迎" + this.client_name + "进入聊天室");
ChatServer.this.showUserList();
continue;
}
if (fromClientData.startsWith("@")) {
String receiveName = fromClientData.substring(1, fromClientData.indexOf(":"));
String message = fromClientData.substring(fromClientData.indexOf(":") + 1, fromClientData.length());
sendToUser(this.client_name, receiveName, message);
} else {
sendToAllClient(this.client_name + "说:" + fromClientData);
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
客户端
package zpb.practice;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
public class ChatClient {
private static final int port = 8888;
private static final String ip_adress = "127.0.0.1";
private PrintWriter client_out;
private BufferedReader client_in;
private Socket client_socket;
public ChatClient() throws IOException {
client_socket = new Socket(ip_adress, port);
client_in = new BufferedReader(new InputStreamReader(client_socket.getInputStream()));
client_out = new PrintWriter(client_socket.getOutputStream(), true);
new ClientThread().start();
while (true) {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String input = br.readLine();
client_out.println(input);
if (input.equals("退出聊天")) {
client_out.close();
client_in.close();
client_socket.close();
System.exit(886);
}
}
}
public static void main(String[] args) throws IOException {
new ChatClient();
}
private class ClientThread extends Thread implements Runnable {
@Override
public void run() {
try {
String fromServer_data;
while ((fromServer_data = client_in.readLine()) != null) {
System.out.println(fromServer_data);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
代码的实现参考自此博客,十分感谢!