java socket 线程池_程序员:java使用线程池和TCP实现简单多轮聊天系统
最近在做物聯網項目,需要使用TCP和傳感器進行雙向交互,通過這種渠道,找到了下面的代碼,寫成博客主要也是為了記錄一下,以后用到隨時可以看。
代碼實現
服務端
package com.tcp;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.ObjectInputStream.GetField;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class TalkServer {
public static int i = 0;
private static final int PORT = 9620; // 端口號
private static List user_list = new ArrayList(); // 保存連接對象
private ExecutorService exec;//線程池
private ServerSocket server;//用來監聽端口
public static void main(String[] args) {
// 啟動服務器程序
new TalkServer();
}
public TalkServer() {
try {
server = new ServerSocket(PORT);
// 創建一個可根據需要創建新線程的線程池,但是在以前構造的線程可用時將重用它們
exec = Executors.newCachedThreadPool();
System.out.println("服務器已啟動!");
Socket client = null;
while (true) {
client = server.accept(); // 接收客戶連接
user_list.add(client);// 將用戶添加進列表
System.out.println("端口號為: " + user_list.get(i).getPort());// 輸出用戶端口號
i++;// 列表下標加一
exec.execute(new s_talk(client));//運行s_talk方法
}
} catch (IOException e) {
e.printStackTrace();
}
}
static class s_talk implements Runnable {
private Socket socket;
private InputStream is = null;//輸入流
private OutputStream os = null;//輸出流
private String msg;
public s_talk(Socket socket) throws IOException {
this.socket = socket;
is = this.socket.getInputStream();
msg = "【" + this.socket.getPort() + "】進入聊天室!當前聊天室有【"+ user_list.size() + "】人"+"(";
for(Socket st:user_list){
msg+=st.getPort()+",";
}
msg+=")";
System.out.println(msg);
for (Socket client : user_list) {
os = client.getOutputStream();
os.write(msg.getBytes());//把在線人數信息輸出到每個客戶端
}
}
public void run() {
try {
int len;
byte[] b = new byte[1024];//字節
while ((len = is.read(b)) != -1) {
msg = new String(b, 0, len);//將數據存儲到msg
//私聊判定
if (msg.indexOf("@") != -1) {
int n = 0;
String stt = null;
for (n = 0; n < user_list.size() - 1; n++) {
stt = "" + user_list.get(n).getPort();//將端口號轉換為字符串類型
if (msg.indexOf(stt) != -1) {
break;//沒找到此端口號,跳出循環
}
}
String Str = null;
int duan = socket.getPort();
String st = "" + duan;
int num1 = st.length();//端口號長度
int num = msg.length();
Str = msg.substring(num1 + 1, num);
os = user_list.get(n).getOutputStream();//將信息存入輸出流
os.write((socket.getPort() + "對我說:" + Str).getBytes());//打印出私聊信息
//System.out.println("私聊接收端口"+user_list.get(n).getPort());//在服務器顯示私聊端口號及其數據
System.out.println(socket.getPort() +"對"+user_list.get(n).getPort()+ "發送的私聊消息:"+ "發送的數據-------" + Str);
} else
{
//判定退出,trim()用于去掉開頭和結尾的空格
if (msg.trim().equals("bye")) {
user_list.remove(socket);// 刪除一個元素
is.close();//關閉輸入輸出流
os.close();
msg = "【" + socket.getPort()+ "】離開聊天室!當前聊天室有【" + user_list.size()+ "】人";
socket.close();
System.out.println(msg);
for (Socket client : user_list) {
os = client.getOutputStream();
os.write(msg.getBytes());
}
break;
} else
{ //群聊
msg = "【" + socket.getPort() + "】說:" + msg;
System.out.println(msg);
for (Socket client : user_list) {
os = client.getOutputStream();
os.write(msg.getBytes());
}
}
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
客戶端
package com.tcp;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.Socket;
import java.util.Scanner;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class TalkClient {
public static String ip = "127.0.0.1";
private static final int PORT = 9620;
private static ExecutorService exec = Executors.newCachedThreadPool(); // 線程池
public static void main(String[] args) throws Exception {
// 啟動客戶端函數
new TalkClient();
}
public TalkClient() {
try {
Socket socket = new Socket(ip, PORT); // 連接端口
exec.execute(new c_send(socket));// 啟動客戶端線程
System.out.println("【" + socket.getLocalAddress() + "】您好,歡迎來到神華客戶端!");
InputStream is = null;
is = socket.getInputStream();// 創建輸入流
String msg;
int len;
byte[] b = new byte[1024];
while ((len = is.read(b)) != -1) {
msg = new String(b, 0, len);// 將消息存入字節數組并賦給msg
System.out.println(msg);
}
} catch (Exception e) {
e.printStackTrace();
}
}
class c_send implements Runnable {
private Socket socket;// 定義套接字
public c_send(Socket socket) {
this.socket = socket;
}
public void run() {
try {
InputStream is = null;
is = socket.getInputStream();// 獲取輸入輸出流
OutputStream os = null;
os = socket.getOutputStream();
String msg;
while (true) {
String stt = null;
Scanner sc = new Scanner(System.in);// 輸入欲發送的信息
msg = sc.next();// 把值返回給msg并打印
os.write(msg.getBytes());
if (msg.trim().equals("bye")) {
is.close();
os.close();
exec.shutdownNow();//關閉線程池
break;
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
實現效果
客戶端
服務端
以上代碼經過本地測試。
總結
以上是生活随笔為你收集整理的java socket 线程池_程序员:java使用线程池和TCP实现简单多轮聊天系统的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 什么甜品做法简单却特别治愈?
- 下一篇: php设置url,php 设置 url