例子来自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的更多相关文章

  1. java并发编程系列三、Lock和Condition

    有了synchronized为什么还要Lock? 因为Lock和synchronized比较有如下优点 1. 尝试非阻塞地获取锁 2. 获取锁的过程可以被中断 3. 超时获取锁 Lock的标准用法 p ...

  2. Java基础:三步学会Java Socket编程

    Java基础:三步学会Java Socket编程 http://tech.163.com 2006-04-10 09:17:18 来源: java-cn 网友评论11 条 论坛        第一步 ...

  3. Java并发编程系列-(5) Java并发容器

    5 并发容器 5.1 Hashtable.HashMap.TreeMap.HashSet.LinkedHashMap 在介绍并发容器之前,先分析下普通的容器,以及相应的实现,方便后续的对比. Hash ...

  4. Java并发编程系列-(6) Java线程池

    6. 线程池 6.1 基本概念 在web开发中,服务器需要接受并处理请求,所以会为一个请求来分配一个线程来进行处理.如果每次请求都新创建一个线程的话实现起来非常简便,但是存在一个问题:如果并发的请求数 ...

  5. Java并发编程系列-(7) Java线程安全

    7. 线程安全 7.1 线程安全的定义 如果多线程下使用这个类,不过多线程如何使用和调度这个类,这个类总是表示出正确的行为,这个类就是线程安全的. 类的线程安全表现为: 操作的原子性 内存的可见性 不 ...

  6. Java Socket编程题库

    一.    填空题 ___ IP地址____用来标志网络中的一个通信实体的地址.通信实体可以是计算机,路由器等. 统一资源定位符URL是指向互联网"资源"的指针,由4部分组成:协议 ...

  7. 如何为可扩展系统进行Java Socket编程

    从简单I/O到异步非阻塞channel的Java Socket模型演变之旅 上世纪九十年代后期,我在一家在线视频游戏工资工作,在哪里我主要的工作就是编写Unix Unix Berkley Socket ...

  8. WCF编程系列(三)地址与绑定

    WCF编程系列(三)地址与绑定   地址     地址指定了接收消息的位置,WCF中地址以统一资源标识符(URI)的形式指定.URI由通讯协议和位置路径两部分组成,如示例一中的: http://loc ...

  9. Java Socket 编程指南

    Socket,又称为套接字,Socket是计算机网络通信的基本的技术之一.如今大多数基于网络的软件,如浏览器,即时通讯工具甚至是P2P下载都是基于Socket实现的.本文会介绍一下基于TCP/IP的S ...

  10. 【JAVA编码专题】 JAVA字符编码系列三:Java应用中的编码问题

    这两天抽时间又总结/整理了一下各种编码的实际编码方式,和在Java应用中的使用情况,在这里记录下来以便日后参考. 为了构成一个完整的对文字编码的认识和深入把握,以便处理在Java开发过程中遇到的各种问 ...

随机推荐

  1. [转帖]调优"四剑客"的实战演练,福尔摩斯•K带你轻松优化性能

     前言 天下武功,唯快不破.在侦探的世界中,破案效率永远是衡量一名侦探能力的不二法门.作为推理界冉冉升起的新星,大侦探福尔摩斯·K凭借着冷静的头脑.严谨的思维,为我们展现了一场场华丽而热血的推理盛宴. ...

  2. 【转帖】8.JVM双亲委派机制(面试常问)

    目录 1.什么是双亲委派机制? 2.双亲委派机制的优势 3.沙箱安全机制 1.什么是双亲委派机制? 双亲委派机制工作原理:(面试) 1.如果一个类加载器收到了类加载请求,它并不会自己先去加载,而是把这 ...

  3. Springboot 使用nacos鉴权的简单步骤

    Springboot 使用nacos鉴权的简单步骤 背景 前端时间nacos爆出了漏洞. 因为他的默认token固定,容易被利用. 具体的问题为: QVD-2023-6271 漏洞描述:开源服务管理平 ...

  4. Linux执行SQLSERVER语句的简单方法

    背景 因为WTF的原因.经常有人让执行各种乱七八槽的删除语句 因为产品支持了10多种数据库. 这个工作量非常复杂. 为了简单起见,想着能够批量执行部分SQL. 其他的都处理过了,但是SQLSERVER ...

  5. Docker系列教程01--简介

    Docker 入门教程   作者: 阮一峰 日期: 2018年2月 9日 2013年发布至今, Docker 一直广受瞩目,被认为可能会改变软件行业. 但是,许多人并不清楚 Docker 到底是什么, ...

  6. 给python脚本传递命令行参数

    记录一下给python脚本传参数的几种方式 最简单的方式 在cmd/bat脚本中调用python脚本传递参数 #传递参数 python test.py arg1 arg2 arg3 #在python中 ...

  7. 【主流技术】实战之 Spring Boot 中集成微信支付(小程序)

    前言 微信支付是企业级项目中经常使用到的功能,作为后端开发人员,完整地掌握该技术是十分有必要的. 以下是经过真实商业项目实践的集成步骤,包括注册流程.调用过程.代码demo(经过脱敏)等,希望我的分享 ...

  8. Paddlenlp之UIE分类模型【以情感倾向分析新闻分类为例】含智能标注方案)

    相关文章: Paddlenlp之UIE模型实战实体抽取任务[打车数据.快递单] 项目连接:百度AIstudio直接fork我的项目就可以复现 Paddlenlp之UIE分类模型[以情感倾向分析新闻分类 ...

  9. 2.0 熟悉CheatEngine修改器

    Cheat Engine 一般简称为CE,它是一款功能强大的开源内存修改工具,其主要功能包括.内存扫描.十六进制编辑器.动态调试功能于一体,且该工具自身附带了脚本工具,可以用它很方便的生成自己的脚本窗 ...

  10. 19.5 Boost Asio 传输结构体

    同步模式下的结构体传输与原生套接字实现方式完全一致,读者需要注意的是在接收参数是应该使用socket.read_some函数读取,发送参数则使用socket.write_some函数实现,对于套接字的 ...