Java Socket程式設計系列(四)開發支援多客戶端訪問的Server
例子來自Java官方教程,稍作調整。
上一篇介紹了單客戶端訪問的Server實現,這一篇實現的是多個客戶端請求服務端,根據服務端提示進行一系列操作。
協議類(和系列三一樣沒變):
package com.dylan.socket;
/**
* @author xusucheng
* @create 2017-12-24
**/
public class KnockKnockProtocol {
private static final int WAITING = 0;
private static final int SENTKNOCKKNOCK = 1;
private static final int SENTCLUE = 2;
private static final int ANOTHER = 3;
private static final int NUMJOKES = 5;
private int state = WAITING;
private int currentJoke = 0;
private String[] clues = { "Turnip", "Little Old Lady", "Atch", "Who", "Who" };
private String[] answers = { "Turnip the heat, it's cold in here!",
"I didn't know you could yodel!",
"Bless you!",
"Is there an owl in here?",
"Is there an echo in here?" };
public String processInput(String theInput) {
String theOutput = null;
if (state == WAITING) {
theOutput = "Knock! Knock!";
state = SENTKNOCKKNOCK;
} else if (state == SENTKNOCKKNOCK) {
if (theInput.equalsIgnoreCase("Who's there?")) {
theOutput = clues[currentJoke];
state = SENTCLUE;
} else {
theOutput = "You're supposed to say \"Who's there?\"! " +
"Try again. Knock! Knock!";
}
} else if (state == SENTCLUE) {
if (theInput.equalsIgnoreCase(clues[currentJoke] + " who?")) {
theOutput = answers[currentJoke] + " Want another? (y/n)";
state = ANOTHER;
} else {
theOutput = "You're supposed to say \"" +
clues[currentJoke] +
" who?\"" +
"! Try again. Knock! Knock!";
state = SENTKNOCKKNOCK;
}
} else if (state == ANOTHER) {
if (theInput.equalsIgnoreCase("y")) {
theOutput = "Knock! Knock!";
if (currentJoke == (NUMJOKES - 1))
currentJoke = 0;
else
currentJoke++;
state = SENTKNOCKKNOCK;
} else {
theOutput = "Bye.";
state = WAITING;
}
}
return theOutput;
}
}
伺服器端:
package com.dylan.socket;
import java.io.IOException;
import java.net.ServerSocket;
/**
* @author xusucheng
* @create 2017-12-24
**/
public class KKMultiServer {
private static final int PORT = 8858;
public static void main(String[] args) {
boolean listening = true;
try (ServerSocket serverSocket = new ServerSocket(PORT)) {
while (listening) {
new KKMultiServerThread(serverSocket.accept()).start();
}
} catch (IOException e) {
System.err.println("Could not listen on port " + PORT);
System.exit(-1);
}
}
}
伺服器多執行緒類(核心):
package com.dylan.socket;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
/**
* @author xusucheng
* @create 2017-12-24
**/
public class KKMultiServerThread extends Thread{
private Socket socket = null;
public KKMultiServerThread(Socket socket) {
super("KKMultiServerThread");
this.socket = socket;
}
public void run() {
try (
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
BufferedReader in = new BufferedReader(
new InputStreamReader(
socket.getInputStream()));
) {
String inputLine, outputLine;
KnockKnockProtocol kkp = new KnockKnockProtocol();
outputLine = kkp.processInput(null);
out.println(outputLine);
while ((inputLine = in.readLine()) != null) {
outputLine = kkp.processInput(inputLine);
out.println(outputLine);
if (outputLine.equals("Bye."))
break;
}
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
客戶端:
package com.dylan.socket;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;
/**
* @author xusucheng
* @create 2017-12-24
**/
public class KnockKnockClient {
private static final String HOST="127.0.0.1";
private static final int PORT=8858;
public static void main(String[] args) throws IOException {
/*if (args.length != 2) {
System.err.println(
"Usage: java EchoClient <host name> <port number>");
System.exit(1);
}
String hostName = args[0];
int portNumber = Integer.parseInt(args[1]);*/
try (
Socket kkSocket = new Socket(HOST, PORT);
PrintWriter out = new PrintWriter(kkSocket.getOutputStream(), true);
BufferedReader in = new BufferedReader(
new InputStreamReader(kkSocket.getInputStream()));
) {
BufferedReader stdIn =
new BufferedReader(new InputStreamReader(System.in));
String fromServer;
String fromUser;
while ((fromServer = in.readLine()) != null) {
System.out.println("Server: " + fromServer);
if (fromServer.equals("Bye."))
break;
fromUser = stdIn.readLine();
if (fromUser != null) {
System.out.println("Client: " + fromUser);
out.println(fromUser);
}
}
} catch (UnknownHostException e) {
System.err.println("Don't know about host " + HOST);
System.exit(1);
} catch (IOException e) {
System.err.println("Couldn't get I/O for the connection to " +
HOST);
System.exit(1);
}
}
}
相關文章
- Hexo多客戶端同步問題Hexo客戶端
- server端雙socket 設計方式Server
- Java Socket程式設計Java程式設計
- TCP程式設計之服務端和客戶端的開發TCP程式設計服務端客戶端
- java併發程式設計系列:java併發程式設計背景知識Java程式設計
- socket程式設計中常見的概念問題!程式設計
- Java網路程式設計:QQ郵件傳送客戶端程式設計Java程式設計客戶端
- Java 程式設計開發Java程式設計
- Python socket的客戶端Python客戶端
- Java 網路程式設計 —— Socket 詳解Java程式設計
- C#Socket伺服器與客戶端的開發(3)C#伺服器客戶端
- SOCKET程式設計程式設計
- 【JAVA 網路程式設計系列】Netty -- 基本編解碼方式的支援Java程式設計Netty
- 「完整案例」基於Socket開發TCP傳輸客戶端TCP客戶端
- Socket最簡單的客戶端與服務端通訊-Java客戶端服務端Java
- java併發程式設計系列:牛逼的AQS(上)Java程式設計AQS
- java併發程式設計系列:牛逼的AQS(下)Java程式設計AQS
- C#WebSocket服務端處理多客戶端連線C#Web服務端客戶端
- Socket程式設計模型程式設計模型
- socket程式設計(1)程式設計
- Python socket程式設計Python程式設計
- golang中的socket程式設計Golang程式設計
- 微信小程式開發系列 (四) :微信小程式的頁面跳轉路由設計微信小程式路由
- mysql賬戶新增遠端訪問MySql
- Java程式設計師必讀:最新流行的Java開發程式設計技術Java程式設計師
- 【趣味設計模式系列】之【訪問者模式】設計模式
- Socket程式設計入門(基於Java實現)程式設計Java
- Java併發程式設計系列之Semaphore詳解Java程式設計
- java併發程式設計系列:wait/notify機制Java程式設計AI
- 併發程式設計(四)程式設計
- 針對Java程式設計師的20個Spring MVC訪談問題Java程式設計師SpringMVC
- Python 中的 Socket 程式設計(指南)Python程式設計
- 網路程式設計-socket程式設計
- socket網路程式設計程式設計
- socket程式設計實戰程式設計
- Socket程式設計基礎程式設計
- HttpClient客戶端網路程式設計——高可用、高併發HTTPclient客戶端程式設計
- 如何用Java Socket實現一個簡單的Redis客戶端JavaRedis客戶端
- windows server 2012更改遠端埠,限制IP訪問WindowsServer