Java Socket编程系列(三)开发支持单客户端访问的Server
例子来自Java官方教程,稍作调整。
实现的是单个客户端请求服务端,根据服务端提示进行一系列操作。
协议类:
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.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
/**
* @author xusucheng
* @create 2017-12-24
**/
public class KnockKnockServer {
private static final int PORT = 8858;
public static void main(String[] args) throws IOException {
/*if (args.length != 1) {
System.err.println("Usage: java KnockKnockServer <port number>");
System.exit(1);
}
int portNumber = Integer.parseInt(args[0]);*/
try (
ServerSocket serverSocket = new ServerSocket(PORT);
Socket clientSocket = serverSocket.accept();
PrintWriter out =
new PrintWriter(clientSocket.getOutputStream(), true);
BufferedReader in = new BufferedReader(
new InputStreamReader(clientSocket.getInputStream()));
) {
String inputLine, outputLine;
// Initiate conversation with client
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;
}
} catch (IOException e) {
System.out.println("Exception caught when trying to listen on port "
+ PORT + " or listening for a connection");
System.out.println(e.getMessage());
}
}
}
客户端:
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);
}
}
}
Java Socket编程系列(三)开发支持单客户端访问的Server的更多相关文章
- java并发编程系列三、Lock和Condition
有了synchronized为什么还要Lock? 因为Lock和synchronized比较有如下优点 1. 尝试非阻塞地获取锁 2. 获取锁的过程可以被中断 3. 超时获取锁 Lock的标准用法 p ...
- Java基础:三步学会Java Socket编程
Java基础:三步学会Java Socket编程 http://tech.163.com 2006-04-10 09:17:18 来源: java-cn 网友评论11 条 论坛 第一步 ...
- Java并发编程系列-(5) Java并发容器
5 并发容器 5.1 Hashtable.HashMap.TreeMap.HashSet.LinkedHashMap 在介绍并发容器之前,先分析下普通的容器,以及相应的实现,方便后续的对比. Hash ...
- Java并发编程系列-(6) Java线程池
6. 线程池 6.1 基本概念 在web开发中,服务器需要接受并处理请求,所以会为一个请求来分配一个线程来进行处理.如果每次请求都新创建一个线程的话实现起来非常简便,但是存在一个问题:如果并发的请求数 ...
- Java并发编程系列-(7) Java线程安全
7. 线程安全 7.1 线程安全的定义 如果多线程下使用这个类,不过多线程如何使用和调度这个类,这个类总是表示出正确的行为,这个类就是线程安全的. 类的线程安全表现为: 操作的原子性 内存的可见性 不 ...
- Java Socket编程题库
一. 填空题 ___ IP地址____用来标志网络中的一个通信实体的地址.通信实体可以是计算机,路由器等. 统一资源定位符URL是指向互联网"资源"的指针,由4部分组成:协议 ...
- 如何为可扩展系统进行Java Socket编程
从简单I/O到异步非阻塞channel的Java Socket模型演变之旅 上世纪九十年代后期,我在一家在线视频游戏工资工作,在哪里我主要的工作就是编写Unix Unix Berkley Socket ...
- WCF编程系列(三)地址与绑定
WCF编程系列(三)地址与绑定 地址 地址指定了接收消息的位置,WCF中地址以统一资源标识符(URI)的形式指定.URI由通讯协议和位置路径两部分组成,如示例一中的: http://loc ...
- Java Socket 编程指南
Socket,又称为套接字,Socket是计算机网络通信的基本的技术之一.如今大多数基于网络的软件,如浏览器,即时通讯工具甚至是P2P下载都是基于Socket实现的.本文会介绍一下基于TCP/IP的S ...
- 【JAVA编码专题】 JAVA字符编码系列三:Java应用中的编码问题
这两天抽时间又总结/整理了一下各种编码的实际编码方式,和在Java应用中的使用情况,在这里记录下来以便日后参考. 为了构成一个完整的对文字编码的认识和深入把握,以便处理在Java开发过程中遇到的各种问 ...
随机推荐
- Java开发者的Python快速进修指南:探索15种独特的Python特殊方法
概述 在Python中,特殊方法(也称为魔术方法)是由Python解释器自动调用的,我们不需要手动调用它们,而是使用内置函数来间接地使用它们.举个例子,我们可以实现特殊方法__len__(),然后通过 ...
- Oceanbase开源版 数据库恢复MySQL数据库的过程
# Oceanbase开源版 数据库恢复MySQL数据库的过程 背景 想进行一下Oceanbase数据库的兼容性验证. 想着用app create 数据库的方式周期比较长. 所以我想着换一套 备份恢复 ...
- [转帖]TiDB 使用 dumpling 导出数据,并使用 lightning 导入到另一个 TiDB 库
本文介绍从 TiDB-A 库导出数据到 TiDB-B 库: 导出 Dumpling 包含在 tidb-toolkit 安装包中,可在此下载. 从 TiDB/MySQL 导出数据 需要的权限 SELEC ...
- [转帖]《Linux性能优化实战》笔记(十五)—— 磁盘IO的工作原理
前一篇介绍了文件系统的工作原理,这一篇来看看磁盘IO的工作原理 一. 磁盘 1. 按存储介质分类 磁盘是可以持久化存储的设备,根据存储介质的不同,常见磁盘可以分为两类:机械磁盘和固态磁盘. 机械磁盘, ...
- [转帖]Jmeter中如何读取MYSQL数据作为请求参数
在项目测试过程中,我经常需要将数据库中的数据作为参数传递到请求中.Jmeter中MYSQL数据库连接操作过程如下: 1.下载/n导入mysql的jdbc驱动包 下载mysql驱动包地址: http:/ ...
- [转帖]通过配置优化KingbaseES服务器性能
目录 1. 概述 2. 数据库应用类型 3. 服务器参数 3.1. max_connections 3.2. shared_buffers 3.3. effective_cache_size 3.4. ...
- [转帖]Xargs用法详解
https://www.cnblogs.com/cheyunhua/p/8796433.html 1. 简介 之所以能用到这个命令,关键是由于很多命令不支持|管道来传递参数,而日常工作中有有这个必要, ...
- Nginx与Tomcat作为前端服务器的性能比较
Nginx与Tomcat作为前端服务器的性能比较 摘要 最近总遇到使用tomcat还是使用nginx进行前端文件访问的争论 想着出差周末在酒店, 可以自己进行一下简单的测试. 希望能够对未来的工作进行 ...
- Java进程 OOM的多种情况
Java进程 OOM的多种情况 摘要 OOM 其实有多种: 第一类是JVM原生自发处理的, 这种也分为多种情况. 1. 堆区使用了比较多,并且大部分对象都还有引用, GC不出来可用内存, 这是要给对象 ...
- [转帖]SPEC测试arm服务器性能,SPECJVM2008测试处理器性能_服务器评测与技术-中关村在线...
首先,我们使用SPECJVM2008测试最新至强E5处理器的虚拟化性能. SPECJVM2008是一种通用的多线程Java基准测试工具,它能够反映JRE(Java Runtime Environmen ...