Java TCP的基本操作参考前一篇:Java 网络编程 – 基于TCP实现文件上传

实现多用户操作之前先实现以下单用户操作,假设目前有一个用户:

账号:zs

密码:123

服务端:

public class LoginServer {
public static void main(String[] args) throws IOException {
System.out.println("=========server========");
// 1、使用serverSocket 创建服务端
ServerSocket server = new ServerSocket(8888);
// 2、阻塞式连接
Socket socket = server .accept();
// 3、操作
DataInputStream dis = new DataInputStream(socket.getInputStream());
String datas = dis.readUTF();
// 解析用户信息
String[] dataArray = datas.split("&");
String uname = null;
String pwd = null;
for (String info : dataArray) {
String[] userInfo = info.split("=");
if("uname".equals(userInfo[0])) {
uname = userInfo[1];
System.out.println("用户名:" + uname);
}else if("pwd".equals(userInfo[0])) {
pwd = userInfo[1];
System.out.println("密码:" + pwd);
}
}
// 输出 模拟和数据库比较信息
DataOutputStream dos = new DataOutputStream(socket.getOutputStream());
if(uname.equals("zs") && pwd.equals("123")) {
dos.writeUTF("登录成功,欢迎回来");
}else {
dos.writeUTF("用户名或密码错误");
}
// 4、释放资源
dos.close();
dis.close();
socket.close();
server.close();
}
}

客户端:

public class LoginClient {
public static void main(String[] args) throws IOException, IOException {
System.out.println("=========client========");
// 1、使用Socket 创建客户端
Socket client = new Socket("localhost", 8888);
// 2、操作
// 输入
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
System.out.print("请输入用户名:");
String uname = br.readLine();
System.out.print("请输入用密码:");
String pwd = br.readLine();
DataOutputStream dos = new DataOutputStream(client.getOutputStream());
dos.writeUTF("uname=" + uname +"&pwd=" + pwd);
dos.flush();
// 接收服务端响应
DataInputStream dis = new DataInputStream(client.getInputStream());
String response = dis.readUTF();
System.out.println(response);
// 3、释放资源
dis.close();
dos.close();
br.close();
client.close();
}
}

运行测试:

现在实现了一个用户登录操作,接下来模拟多用户登录。

对于服务端来说一个连接就是一个socket,要满足多用户登录的需求,如果直接在现有代码上加上while循环,需要一个用户操作完,下一个用户接着操作,这样很不合理,明显的我们要加入多线程,并且现在所有代码都写在main 方法里面,不好维护。

如果使用lambda表达式,代码比较多,看起来比较累。

我们还是用静态内部类封装一下每一个类

封装服务端:

public class LoginMultiServer {
public static void main(String[] args) throws IOException {
System.out.println("=========server========");
// 1、使用serverSocket 创建服务端
ServerSocket server = new ServerSocket(8888);
boolean isRuning = true;
while (isRuning) {
// 2、阻塞式连接
Socket socket = server.accept();
System.out.println("一个客户端建立了连接");
// 3、操作
new Thread(new Channel(socket)).start();
}
server.close();
} // 一个Channel 代表一个客户端
static class Channel implements Runnable{
private Socket socket;
private DataInputStream dis;
private DataOutputStream dos; public Channel(Socket socket) {
this.socket = socket;
try {
// 输入
dis = new DataInputStream(socket.getInputStream());
// 输出
dos = new DataOutputStream(socket.getOutputStream());
} catch (IOException e) {
e.printStackTrace();
release(); // 一个出错就不用玩了
} } // 接收数据
public String receive() {
String datas = "";
try {
datas = dis.readUTF();
} catch (IOException e) {
e.printStackTrace();
}
return datas;
} // 发送数据
public void send(String msg) {
try {
dos.writeUTF(msg);
} catch (IOException e) {
e.printStackTrace();
}
} // 释放资源
public void release() {
try {
if(null != dos)
dos.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
if(null != dis)
dis.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
if(null != dos)
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void run() { // 3、操作
String datas = receive();
// 解析用户信息
String[] dataArray = datas.split("&");
String uname = null;
String pwd = null;
for (String info : dataArray) {
String[] userInfo = info.split("=");
if ("uname".equals(userInfo[0])) {
uname = userInfo[1];
System.out.println("用户名:" + uname);
} else if ("pwd".equals(userInfo[0])) {
pwd = userInfo[1];
System.out.println("密码:" + pwd);
}
}
// 输出 模拟和数据库比较信息
if (uname.equals("zs") && pwd.equals("123")) {
send("登录成功,欢迎回来");
} else {
send("用户名或密码错误");
}
// 4、释放资源
release();
} }
}

封装客户端:

public class LoginMultiClient {
public static void main(String[] args) throws IOException, IOException {
System.out.println("=========client========");
// 1、使用Socket 创建客户端
Socket client = new Socket("localhost", 8888);
// 2、操作
// 输入
new Send(client).send();
// 接收服务端响应
new Receive(client).receice();
// 3、释放资源
client.close();
} // 发送
static class Send{
private Socket client;
private BufferedReader br;
private DataOutputStream dos;
private String msg;
public Send(Socket client) {
try {
this.client = client;
br = new BufferedReader(new InputStreamReader(System.in));
this.msg = init();
dos = new DataOutputStream(client.getOutputStream());
} catch (IOException e) {
e.printStackTrace();
}
} private String init() {
try {
System.out.print("请输入用户名:");
String uname = br.readLine();
System.out.print("请输入用密码:");
String pwd = br.readLine();
return "uname=" + uname +"&pwd=" + pwd;
} catch (IOException e) {
e.printStackTrace();
}
return "";
} public void send() {
try {
dos.writeUTF(this.msg);
dos.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
} // 接收
static class Receive{
private Socket client;
private DataInputStream dis;
public Receive(Socket client) {
this.client = client;
try {
dis = new DataInputStream(client.getInputStream());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} public void receice() {
String response;
try {
response = dis.readUTF();
System.out.println(response);
} catch (IOException e) {
e.printStackTrace();
}
}
}
}

封装之后,main 方法里可以比较简洁的书写逻辑代码了。

运行测试:

Java 网络编程 -- 基于TCP 模拟多用户登录的更多相关文章

  1. Java 网络编程 -- 基于TCP实现文件上传

    Java TCP 操作基本流程 一.创建服务器 1.指定端口, 使用serverSocket创建服务器 2.阻塞式连接 accept 3.操作:输入流 输出流 4.释放资源 二.创建客户端 1.使用S ...

  2. Java 网络编程 -- 基于TCP 实现聊天室 群聊 私聊

    分析: 聊天室需要多个客户端和一个服务端. 服务端负责转发消息. 客户端可以发送消息.接收消息. 消息分类: 群聊消息:发送除自己外所有人 私聊消息:只发送@的人 系统消息:根据情况分只发送个人和其他 ...

  3. JAVA基础知识之网络编程——-基于TCP通信的简单聊天室

    下面将基于TCP协议用JAVA写一个非常简单的聊天室程序, 聊天室具有以下功能, 在服务器端,可以接受客户端注册(用户名),可以显示注册成功的账户 在客户端,可以注册一个账号,并用这个账号发送信息 发 ...

  4. java网络编程基础——TCP网络编程一

    基于TCP协议的网络编程 TCP/IP协议是一种可靠的网络协议,它的通信的两端各自建立一个Socket,从而在通信的两端之间形成网络虚拟链路. Java使用Socket对象来代表两端的通信端口,并通过 ...

  5. 网络编程——基于TCP协议的Socket编程,基于UDP协议的Socket编程

    Socket编程 目前较为流行的网络编程模型是客户机/服务器通信模式 客户进程向服务器进程发出要求某种服务的请求,服务器进程响应该请求.如图所示,通常,一个服务器进程会同时为多个客户端进程服务,图中服 ...

  6. java 网络编程 UDP TCP

    网络编程 网络编程主要用于解决计算机与计算机(手机.平板..)之间的数据传输问题. 网络编程: 不需要基于html页面就可以达到数据之间的传输. 比如: feiQ , QQ , 微信....网页编程: ...

  7. (网络编程)基于tcp(粘包问题) udp协议的套接字通信

    import   socket 1.通信套接字(1人1句)服务端和1个客户端 2.通信循环(1人多句)服务端和1个客户端 3.通信循环(多人(串行)多句)多个客户端(服务端服务死:1个客户端---&g ...

  8. java网络编程基础——TCP网络编程三

    AIO实现非阻塞通信 java7 NIO2 提供了异步Channel支持,这种异步Channel可以提供更高效的IO,这种基于异步Channel的IO被称为异步IO(Asynchronous IO) ...

  9. java 网络编程基础 TCP/IP协议:服务端ServerSocket;客户端Socket; 采用多线程方式处理网络请求

    1.Java中客户端和服务器端通信的简单实例 Java中能接收其他通信实体连接请求的类是ServerSocket,ServerSocket对象用于监听来自客户端的Socket连接,如果没有连接,它将一 ...

随机推荐

  1. arcgis10.4.X的oracle数据库要求

    受支持的数据库版本:(标准版/标准独立版/企业版) Oracle 11g R2(64 位)11.2.0.4 Oracle 12c R1(64 位)12.1.0.2 受支持的操作系统: 数据库 支持的操 ...

  2. vue 对px 做rem 自动转换

    插件:postcss 安装: npm install postcss-pxtorem vue.config.js 配置 css: { loaderOptions: { postcss: { plugi ...

  3. dp例题03. 最大子矩阵和

    题目Description: 给出一个矩阵, 求子矩阵(可以是其本身)数之和的最大值 Input: 第一行 为行数n和列数m       (n≤500, m≤500) 接下来为一个n行m列的矩阵 (每 ...

  4. Activiti网关--并行网关

    1.什么是并行网关 并行网关允许将流程分成多条分支,也可以把多条分支汇聚到一起,并行网关的功能是基于进 入和外出顺序流的: fork 分支: 并行后的所有外出顺序流,为每个顺序流都创建一个并发分支. ...

  5. vue中的js引入图片,使用require相关问题

    vue中的js引入图片,必须require进来 或者引用网络地址 <template> <div class="home"> <img alt=&qu ...

  6. thinkphp后端开发ajax接口开发测试

    数据自动填充,Firefox的网络查看JSON数据,查错. 同时,用getLastSql函数查询,并且开启日志文件记录网页执行的全过程,还可以用thinkPHP内置的trace的跟踪. 谁有更好地方法 ...

  7. 开启sftp服务日志并限制sftp访问目录

    目录导航 目录导航 开启sftp日志 修改sshd_config 修改syslogs 重启服务查看日志 限制sftp用户操作目录 前提说明 1. home目录做根目录 2. 单独创建目录做根目录 方法 ...

  8. django-rest-framework视图和url

    django-rest-framework视图 GenericView class GenericView(GenericAPIView): queryset = models.Role.object ...

  9. flask开启调试的四种模式

    flask开启调试的四种模式 在app.run()中加一个参数, 'debug=True'就可以开启debug模式 from flask import Flask app = Flask(__name ...

  10. npm install报错:chromedriver@2.27.2 install: node install.js

    报错: 刚开始以为是 node 或 npm 版本问题,前前后后折腾了好久,终于解决了 解决: 如果执行过npm install,先删除 node_modules 文件夹,不然运行的时候可能会报错 执行 ...