主程序Client.java: 启动5个Customer线程,为每个线程命名为customer_i(i=0..4)。
Customer.java: 每隔0.1秒,向服务端发起一次socket连接请求,连接成功后,随机生成一个地区号,并发出请求报文,然后接收响应报文并按要求显示,关闭本次连接。共发起10次连接。
主程序Server.java: 启动10个Worker线程,为了便于输出调试,为每个线程命名为worker_i(i=0..9)。开启5001(或其他)服务端口,接收客户端的响应,并将其分流到Worker线程组。
Worker.java: 完成服务请求。
- Client.java:
public class Client {
public static void main(String[] args) {
for (int i = 0; i<5; i++) {
Customer customer = new Customer();
Thread thread = new Thread(customer);
thread.setName("customer_" + i);
thread.start();
}
}
}
- Customer.java:
public class Customer implements Runnable{
int serverLen = 12;//服务线程名称(12字节)、地区名称(12字节)、地区编号(6字节)
int noLen = 6;
int nameLen = 12;
@Override
public void run() {
try {
clientConnect();
} catch (InterruptedException | IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private void clientConnect() throws InterruptedException, IOException {
Socket socket = null;
OutputStream outputStream = null;
InputStream inputStream = null;
for (int i = 0; i < 10; i++) {
Thread.sleep(100);//每隔0.1秒,向服务端发起一次socket连接请求
//客户端发送消息
socket = new Socket("localhost", 7777);
outputStream = socket.getOutputStream();
outputStream.write(dealMessage());
outputStream.flush();
//客户端接收服务器消息
inputStream = socket.getInputStream();
byte[] buf = new byte[30];
int len = inputStream.read(buf);
String nameServer = new String(buf, 0, serverLen); //线程名称
String nameCity = new String(buf, serverLen, nameLen); //城市名称
String noCity = new String(buf, nameLen+serverLen, noLen); //城市编码
System.out.println(Thread.currentThread().getName() + " receive " + nameServer.trim() + " response " + noCity.trim() + " " + nameCity.trim());
socket.shutdownInput();
//关闭资源
inputStream.close();
outputStream.close();
}
}
// 处理客户端发送的报文
public byte[] dealMessage() {
int serverLen = 12; //服务线程名称(12字节)、地区名称(12字节)、地区编号(6字节)
int noLen = 6;
int nameLen = 12;
Random random = new Random();
int randNum = random.nextInt(412 - 402 + 1) + 402; //生成0402-0412随机数
// 城市编号前补空格
String noCity = String.format("%04d",randNum);
byte[] noCityByte = new byte[noLen];
for(int i = 0; i < noLen; i++) {
if (i < noLen - noCity.getBytes().length) {
noCityByte[i] = new String(" ").getBytes()[0];}
else {
noCityByte[i] = noCity.getBytes()[i - (noLen - noCity.getBytes().length)];
}
}
// 客户端线程名称前补空格
String nameClient = Thread.currentThread().getName();
byte[] nameServerByte = new byte[serverLen];
for(int i = 0; i < serverLen; i++) {
if (i < serverLen - nameClient.getBytes().length) {
nameServerByte[i] = new String(" ").getBytes()[0];}
else {
nameServerByte[i] = nameClient.getBytes()[i - (serverLen - nameClient.getBytes().length)];
}
}
String receiveMeg = new String(nameServerByte) + new String(noCityByte);
return receiveMeg.getBytes();
}
}
- Server.java:
public class Server {
private static ServerSocket serverSocket;
public static void main(String[] args) throws InterruptedException, IOException {
LinkedBlockingQueue<Socket> socketQueue = new LinkedBlockingQueue<Socket>(); //保存接收的Socket
Socket socket = null;
serverSocket = new ServerSocket(7777);
//开启10个worker线程
for (int i = 0; i < 10; i++) {
Worker worker = new Worker(socketQueue);
Thread thread = new Thread(worker);
thread.setName("worker_" + i);
thread.start();
}
while(true) {
socket = serverSocket.accept();
socketQueue.put(socket);
}
// serverSocket.close();
}
}
- Worker.java:
public class Worker implements Runnable{
private LinkedBlockingQueue<Socket> socketQueue;
int clientLen = 12;//客户端线程名称(12字节)、地区名称(12字节)、地区编号(6字节)
int noLen = 6;
int nameLen = 12;
int serverLen = 12;
public Worker() {
super();
}
public Worker(LinkedBlockingQueue<Socket> socketQueue) {
super();
this.socketQueue = socketQueue;
}
@Override
public void run() {
try {
serverDeal();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//接收客户端消息,发送客户端处理后的信息
public void serverDeal() throws InterruptedException, IOException {
//接收信息
InputStream inputStream = null;
OutputStream outputStream = null;
while(true) {
//服务器接收客户端消息
Socket socket = socketQueue.take();
inputStream = socket.getInputStream();
byte[] buf = new byte[18];
int len = inputStream.read(buf);
String nameClient= new String(buf, 0, clientLen); //客户端线程名称
String noCity = new String(buf, clientLen, noLen); //城市编码
System.out.println(Thread.currentThread().getName() + " receive " + nameClient.trim() + " request " + noCity.trim());
//服务器发送消息
outputStream = socket.getOutputStream();
outputStream.write(returnCityName(noCity));
outputStream.flush();
socket.shutdownInput();
//关闭资源
outputStream.close();
inputStream.close();
socket.close();
}
}
public byte[] returnCityName(String noCity) throws InterruptedException, IOException {
//取出客户端请求编码对应的城市名称
HashMap<String, String> map = data();
String nameCity = map.get(noCity.trim());
String nameServer = Thread.currentThread().getName();
//为线程名称补充空格使其占用字节数为12
byte[] nameServerByte = new byte[serverLen];
for(int i = 0; i < serverLen; i++) {
if (i < serverLen - nameServer.getBytes().length) {
nameServerByte[i] = new String(" ").getBytes()[0];}
else {
nameServerByte[i] = nameServer.getBytes()[i - (serverLen - nameServer.getBytes().length)];
}
}
/*byte[] noCityByte = new byte[noLen];
for(int i = 0; i < noLen; i++) {
System.out.println(noLen - noCity.getBytes().length);
if (i < noLen - noCity.getBytes().length) {
noCityByte[i] = new String(" ").getBytes()[0];}
else {
noCityByte[i] = noCity.getBytes()[i - (noLen - noCity.getBytes().length)];
}
}*/
//城市名称占12个字节
byte[] nameCityByte = new byte[nameLen];
for(int i = 0; i < nameLen; i++) {
if( i < nameLen - nameCity.getBytes().length) {
nameCityByte[i] = new String(" ").getBytes()[0];}
else {
nameCityByte[i] = nameCity.getBytes()[i - (nameLen - nameCity.getBytes().length)];
}
}
return (new String(nameServerByte) + new String(nameCityByte) + noCity).getBytes();
}
//hashmap存储数据
public HashMap<String, String> data() {
HashMap<String, String> map = new HashMap<String, String>();
map.put("0402", "石家庄");
map.put("0403", "唐山");
map.put("0404", "秦皇岛");
map.put("0405", "邯郸");
map.put("0406", "邢台");
map.put("0407", "衡水");
map.put("0408", "沧州");
map.put("0409", "保定");
map.put("0410", "廊坊");
map.put("0411", "承德");
map.put("0412", "张家口");
return map;
}
}
结果截图:
服务器:
客户端:
?
?
?
|