java socket通信例子
程序员文章站
2022-04-24 13:27:59
...
java socket 通信,简易聊天功能,
参考:http://www.cnblogs.com/feijian/p/4461087.html
服务端:
package com.lw.socket.server;
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.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
public class ChatServer extends ServerSocket {
private static final int SERVER_PORT = 8000;
private static final String KEY = "key";
private static boolean isPrint = false;// 是否输出消息标志
private static List<String> user_list = new ArrayList<>();// 登录用户集合
private static List<ServerClientThread> thread_list = new ArrayList<ServerClientThread>();// 服务器已启用线程集合
private static LinkedList<String> message_list = new LinkedList<String>();// 存放消息队列
/**
* 创建服务端Socket,创建向客户端发送消息线程,监听客户端请求并处理
*/
public ChatServer() throws IOException {
super(SERVER_PORT);// 创建ServerSocket
new PrintOutThread();// 创建向客户端发送消息线程
new ServerReadThread();// 创建向客户端发送消息线程(服务端输入数据推送到各客户端)
try {
while (true) {// 监听客户端请求,启个线程处理
Socket socket = accept();
new ServerClientThread(socket);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
close();
}
}
/**
* 监听是否有输出消息请求线程类,向客户端发送消息
*/
class PrintOutThread extends Thread {
public PrintOutThread() {
start();
}
@Override
public void run() {
while (true) {
if (isPrint) {// 将缓存在队列中的消息按顺序发送到各客户端,并从队列中清除。
String message = message_list.getFirst();
for (ServerClientThread thread : thread_list) {
thread.sendMessage(message);
}
message_list.removeFirst();
isPrint = message_list.size() > 0 ? true : false;
}
}
}
}
/**
* 服务器向各客户端发送数据的线程
*/
class ServerReadThread extends Thread {
public ServerReadThread() {
start();
}
@Override
public void run() {
BufferedReader br = null;
try {
while (true) {
System.out.println("服务端发送数据输入:");
br = new BufferedReader(new InputStreamReader(System.in));
String send = br.readLine();
DateFormat dateTimeformat = new SimpleDateFormat("HH:mm:ss");
String date = dateTimeformat.format(new Date());
message_list.addLast(date + "【系统消息】:" + send);
isPrint = true;
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (br != null) {
br.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
/**
* 服务器线程类
*/
class ServerClientThread extends Thread {
private Socket client;
private PrintWriter writer;
private BufferedReader reader;
private String name;
public ServerClientThread(Socket s) throws IOException {
client = s;
writer = new PrintWriter(client.getOutputStream(), true);
reader = new BufferedReader(new InputStreamReader(client.getInputStream()));
String read = reader.readLine();
if(KEY.equals(read)) {
writer.println("成功连上聊天室,请输入你的名字:");
start();
}
}
@Override
public void run() {
try {
int flag = 0;
String line = reader.readLine();
while (!"byeClient".equals(line)) {
// 查看在线用户列表
if ("showuser".equals(line)) {
writer.println(this.listOnlineUsers());
line = reader.readLine();
}
// 第一次进入,保存名字
if (flag++ == 0) {
name = line;
user_list.add(name);
thread_list.add(this);
writer.println(name + "你好,可以开始聊天了...");
this.pushMessage("【" + name + "】进入聊天室...");
} else {
this.pushMessage("【" + name + "】 say : " + line);
}
line = reader.readLine();
}
writer.println("byeClient");
} catch (Exception e) {
e.printStackTrace();
} finally {// 用户退出聊天室
try {
client.close();
} catch (IOException e) {
e.printStackTrace();
}
thread_list.remove(this);
user_list.remove(name);
pushMessage("【" + name + "】退出了聊天室");
}
}
// 放入消息队列末尾,准备发送给客户端
private void pushMessage(String msg) {
DateFormat dateTimeformat = new SimpleDateFormat("HH:mm:ss");
String date = dateTimeformat.format(new Date());
message_list.addLast(date + msg);
isPrint = true;
}
// 向客户端发送一条消息
private void sendMessage(String msg) {
writer.println(msg);
}
// 统计在线用户列表
private String listOnlineUsers() {
String s = "--- 在线用户列表 ---\015\012";
for (int i = 0; i < user_list.size(); i++) {
s += "[" + user_list.get(i) + "]\015\012";
}
s += "--------------------";
return s;
}
}
public static void main(String[] args) {
try {
new ChatServer().close();// 启动服务端
} catch (IOException e) {
e.printStackTrace();
}
}
}
客户端:
package com.lw.socket.client;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
public class ChatClient extends Socket {
private static final String SERVER_IP = "127.0.0.1";
private static final int SERVER_PORT = 8000;
private static final String PASSWORD = "pwd";
private static final String KEY = "key";
private Socket client;
private PrintWriter writer;
private BufferedReader reader;
/**
* 与服务器连接,并输入发送消息
*/
public ChatClient() throws Exception {
super(SERVER_IP, SERVER_PORT);
client = this;
writer = new PrintWriter(client.getOutputStream(), true);
reader = new BufferedReader(new InputStreamReader(client.getInputStream()));
new readLineThread();
System.out.println("输入正确的密码连接服务器");
while(true) {
BufferedReader readerIn = new BufferedReader(new InputStreamReader(System.in));
String input = readerIn.readLine();
if(PASSWORD.equals(input)) {
writer.println(KEY);
break;
} else {
System.out.println("输入错误,请重新输入!");
}
}
while (true) {
reader = new BufferedReader(new InputStreamReader(System.in));
String input = reader.readLine();
writer.println(input);
}
}
/**
* 用于监听服务器端向客户端发送消息线程类
*/
class readLineThread extends Thread {
private BufferedReader buff;
public readLineThread() {
try {
buff = new BufferedReader(new InputStreamReader(client.getInputStream()));
start();
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void run() {
try {
while (true) {
String result = buff.readLine();
if ("byeClient".equals(result)) {// 客户端申请退出,服务端返回确认退出
break;
} else {// 输出服务端发送消息
System.out.println(result);
}
}
reader.close();
writer.close();
client.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
try {
new ChatClient().close();// 启动客户端
} catch (Exception e) {
e.printStackTrace();
}
}
}
上一篇: socket通信 server端
下一篇: 你怎么把龙虾叫