【java的socket编程】用socket进行多线程客户端-服务器通信
程序员文章站
2022-03-24 11:37:42
...
文件目录:
chartserver:
public class ChatServer {
private static final int SOCKET_PORT = 52000;
public static ArrayList<SocketBean> mSocketList = new ArrayList<SocketBean>();
private void initServer() {
try {
// 创建一个ServerSocket,用于监听客户端Socket的连接请求
ServerSocket server = new ServerSocket(SOCKET_PORT);
while (true) {
// 每当接收到客户端的Socket请求,服务器端也相应的创建一个Socket
SocketBean socket = new SocketBean(DateUtil.getTimeId(), server.accept());
mSocketList.add(socket);
// 每连接一个客户端,启动一个ServerThread线程为该客户端服务
new Thread(new ServerThread(socket)).start();
}
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
ChatServer server = new ChatServer();
server.initServer();
}
}
ServerThread
public class ServerThread implements Runnable {
private SocketBean mSocket = null;
private BufferedReader mReader = null;
public ServerThread(SocketBean mSocket) throws IOException {
this.mSocket = mSocket;
mReader = new BufferedReader(new InputStreamReader(mSocket.socket.getInputStream()));
}
@Override
public void run() {
try {
String content = null;
// 循环不断地从Socket中读取客户端发送过来的数据
while ((content = mReader.readLine()) != null) {
System.out.println("content="+content);
int pos = content.indexOf("|");
// 包头格式为:动作名称|设备编号|昵称|时间|对方设备编号
String head = content.substring(0, pos);
String body = content.substring(pos+1);
String[] splitArray = head.split(",");
String action = splitArray[0];
System.out.println("action="+action);
if (action.equals("LOGIN")) {
login(splitArray[1], splitArray[2], splitArray[3]);
} else if (action.equals("LOGOUT")) {
logout(splitArray[1]);
break;
} else if (action.equals("SENDMSG")) {
sendmsg("RECVMSG", splitArray[2], splitArray[4], splitArray[1], body);
} else if (action.equals("GETLIST")) {
getlist(splitArray[1]);
} else if (action.equals("SENDPHOTO")) {
sendmsg("RECVPHOTO", splitArray[2], splitArray[4], splitArray[1], body);
} else if (action.equals("SENDSOUND")) {
sendmsg("RECVSOUND", splitArray[2], splitArray[4], splitArray[1], body);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
private void login(String deviceId, String nickName, String loginTime) throws IOException {
for (int i=0; i<ChatServer.mSocketList.size(); i++) {
SocketBean item = ChatServer.mSocketList.get(i);
if (item.id.equals(mSocket.id)) {
item.deviceId = deviceId;
item.nickName = nickName;
item.loginTime = loginTime;
ChatServer.mSocketList.set(i, item);
break;
}
}
}
private String getFriend() {
String friends = "GETLIST,";
for (SocketBean item : ChatServer.mSocketList) {
if (item.deviceId!=null && item.deviceId.length()>0) {
String friend = String.format("|%s,%s,%s", item.deviceId, item.nickName, item.loginTime);
friends += friend;
}
}
return friends;
}
private void getlist(String deviceId) throws IOException {
for (int i=0; i<ChatServer.mSocketList.size(); i++) {
SocketBean item = ChatServer.mSocketList.get(i);
if (item.id.equals(mSocket.id) && item.deviceId.equals(deviceId)) {
PrintStream ps = new PrintStream(item.socket.getOutputStream());
ps.println(getFriend());
break;
}
}
}
private void logout(String deviceId) throws IOException {
for (int i=0; i<ChatServer.mSocketList.size(); i++) {
SocketBean item = ChatServer.mSocketList.get(i);
if (item.id.equals(mSocket.id) && item.deviceId.equals(deviceId)) {
PrintStream ps = new PrintStream(item.socket.getOutputStream());
ps.println("LOGOUT,|");
item.socket.close();
ChatServer.mSocketList.remove(i);
break;
}
}
}
private void sendmsg(String respAction, String otherName, String otherId, String selfId, String message) throws IOException {
for (int i=0; i<ChatServer.mSocketList.size(); i++) {
SocketBean item = ChatServer.mSocketList.get(i);
if (item.deviceId.equals(otherId)) {
String content = String.format("%s,%s,%s,%s|%s",
respAction, selfId, otherName, DateUtil.getNowTime(), message);
System.out.println("resp="+content);
PrintStream ps = new PrintStream(item.socket.getOutputStream());
ps.println(content);
break;
}
}
}
}
socketbean:
public class SocketBean {
public String id;
public Socket socket;
public String deviceId;
public String nickName;
public String loginTime;
public SocketBean(String id, Socket socket) {
this.id = id;
this.socket = socket;
this.deviceId = "";
this.nickName = "";
this.loginTime = "";
}
}
TestServer:
public class TestServer {
private static final int SOCKET_PORT = 51000;
private void initServer() {
try {
// 创建一个ServerSocket,用于监听客户端Socket的连接请求
ServerSocket server = new ServerSocket(SOCKET_PORT);
while (true) {
Socket socket = server.accept();
new Thread(new ServerThread(socket)).start();
}
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
TestServer server = new TestServer();
server.initServer();
}
private class ServerThread implements Runnable {
private Socket mSocket;
private BufferedReader mReader;
public ServerThread(Socket socket) throws IOException {
mSocket = socket;
mReader = new BufferedReader(new InputStreamReader(mSocket.getInputStream()));
}
@Override
public void run() {
try {
String content = null;
// 循环不断地从Socket中读取客户端发送过来的数据
while ((content = mReader.readLine()) != null) {
System.out.println("收到客户端消息:"+content);
PrintStream ps = new PrintStream(mSocket.getOutputStream());
ps.println("hi,很高兴认识你");
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
客户端:
public class MessageTransmit implements Runnable {
private static final String TAG = "MessageTransmit";
// 以下为Socket服务器的ip和端口,根据实际情况修改
private static final String SOCKET_IP = "192.168.0.212";
private static final int SOCKET_PORT = 51000;
private Socket mSocket;
private BufferedReader mReader = null;
private OutputStream mWriter = null;
@Override
public void run() {
mSocket = new Socket();
try {
mSocket.connect(new InetSocketAddress(SOCKET_IP, SOCKET_PORT), 3000);
mReader = new BufferedReader(new InputStreamReader(mSocket.getInputStream()));
mWriter = mSocket.getOutputStream();
// 启动一条子线程来读取服务器的返回数据
new RecvThread().start();
Looper.prepare();
Looper.loop();
} catch (Exception e) {
e.printStackTrace();
}
}
// 定义接收UI线程的Handler对象,App向后台服务器发送消息
public Handler mRecvHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
Log.d(TAG, "handleMessage: "+msg.obj);
// 换行符相当于回车键,表示我写好了发出去吧
String send_msg = msg.obj.toString()+"\n";
try {
mWriter.write(send_msg.getBytes("utf8"));
} catch (Exception e) {
e.printStackTrace();
}
}
};
// 定义消息接收子线程,App从后台服务器接收消息
private class RecvThread extends Thread {
@Override
public void run() {
try {
String content = null;
while ((content = mReader.readLine()) != null) {
// 读取到来自服务器的数据
Message msg = Message.obtain();
msg.obj = content;
SocketActivity.mHandler.sendMessage(msg);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
public class ClientThread implements Runnable {
private static final String TAG = "ClientThread";
private static final String SOCKET_IP = "192.168.253.1";
//private static final String SOCKET_IP = "192.168.0.212";
private static final int SOCKET_PORT = 52000;
public static final String REQUEST_URL = "http://192.168.253.1:8080/UploadTest";
private Context mContext;
private Socket mSocket;
public Handler mRecvHandler;
private BufferedReader mReader = null;
private OutputStream mWriter = null;
public static String ACTION_RECV_MSG = "com.example.network.RECV_MSG";
public static String ACTION_GET_LIST = "com.example.network.GET_LIST";
public static String CONTENT = "CONTENT";
public static String SPLIT_LINE = "|";
public static String SPLIT_ITEM = ",";
public static String LOGIN = "LOGIN";
public static String LOGOUT = "LOGOUT";
public static String SENDMSG = "SENDMSG";
public static String RECVMSG = "RECVMSG";
public static String GETLIST = "GETLIST";
public static String SENDPHOTO = "SENDPHOTO";
public static String RECVPHOTO = "RECVPHOTO";
public static String SENDSOUND = "SENDSOUND";
public static String RECVSOUND = "RECVSOUND";
public ClientThread(Context context) {
mContext = context;
}
@Override
public void run() {
Log.d(TAG, "run");
mSocket = new Socket();
try {
Log.d(TAG, "connect");
mSocket.connect(new InetSocketAddress(SOCKET_IP, SOCKET_PORT), 3000);
mReader = new BufferedReader(new InputStreamReader(mSocket.getInputStream()));
Log.d(TAG, "getOutputStream");
mWriter = mSocket.getOutputStream();
Log.d(TAG, "RecvThread");
// 启动一条子线程来读取服务器相应的数据
new RecvThread().start();
Looper.prepare();
// 定义接收UI线程的Handler对象,App向后台服务器发送消息
// 如果是在Application中启动线程,则mRecvHandler要在线程启动后才能初始化
// 并且要在Looper.prepare之后执行初始化动作
mRecvHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
// 接收到UI线程的用户输入的数据
try {
mWriter.write(msg.obj.toString().getBytes("utf8"));
} catch (Exception e) {
e.printStackTrace();
}
}
};
Looper.loop();
} catch (Exception e) {
e.printStackTrace();
notify(99, e.getMessage());
}
}
// 定义消息接收子线程,App从后台服务器接收消息
private class RecvThread extends Thread {
@Override
public void run() {
String content = null;
try {
while ((content = mReader.readLine()) != null) {
// 读取到来自服务器的数据之后,发送消息通知
ClientThread.this.notify(0, content);
}
} catch (Exception e) {
e.printStackTrace();
ClientThread.this.notify(97, e.getMessage());
}
}
}
private void notify(int type, String message) {
if (type == 99) {
String content = String.format("%s%s%s%s", "ERROR", SPLIT_ITEM, SPLIT_LINE, message);
Intent intent1 = new Intent(ACTION_RECV_MSG);
intent1.putExtra(CONTENT, content);
mContext.sendBroadcast(intent1);
Intent intent2 = new Intent(ACTION_GET_LIST);
intent2.putExtra(CONTENT, content);
mContext.sendBroadcast(intent2);
} else {
int pos = message.indexOf(SPLIT_LINE);
String head = message.substring(0, pos - 1);
String[] splitArray = head.split(SPLIT_ITEM);
String action = "";
if (splitArray[0].equals(RECVMSG)
|| splitArray[0].equals(RECVPHOTO)
|| splitArray[0].equals(RECVSOUND)) {
action = ACTION_RECV_MSG;
} else if (splitArray[0].equals(GETLIST)) {
action = ACTION_GET_LIST;
}
Log.d(TAG, "action=" + action + ", message=" + message);
Intent intent = new Intent(action);
intent.putExtra(CONTENT, message);
mContext.sendBroadcast(intent);
}
}
}
上一篇: 上传和下载