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. 面试刷题28:如何写出安全的java代码?

    对jdk,jvm,java应用程序的攻击多种多样?那么从java程序员的角度,如何写出安全的代码呢? 我是李福春,我在准备面试,今天的题目是:如何写出安全的java代码? 答:这个需要从功能设计到实现 ...

  2. Python第十一章-常用的核心模块03-json模块

    python 自称 "Batteries included"(自带电池, 自备干粮?), 就是因为他提供了很多内置的模块, 使用这些模块无需安装和配置即可使用. 本章主要介绍 py ...

  3. Python面向对象之异常处理

    1:什么是异常 异常就是在我们的程序在运行过程中由于某种错误而引发Python抛出的错误: 异常就是程序运行时发生错误的信号(在程序出现错误时,则会产生一个异常,若程序没有处理它,则会抛出该异常,程序 ...

  4. Node教程——Node+MongoDB案例实现用户信息的增删改查

    想要获取源代码的同学可以留言,我不做git上传了,案例太简单 没必要 综合演练 用户信息的增删改查 需求:你需要实现这样的结果 点击添加可以添加用户,点击删除可以删除点击修改可以修改 代码分析: 1. ...

  5. Java 中的递归

    递归 递归 一种通过调用某个方法来描述需要重复进行的操作.该方法的特点就是可以自己调用自己. 案例一 排队的问题 在生活中,我们经常需要排队.在排队中,我们怎么才能知道自己所排在第几位呢? 我们也许会 ...

  6. 关于C#三层架构增删改查中的“添加”问题

    关于“添加”功能的实现比较简单: 先来一个简单的界面: 然后是代码: ··采用的是三层架构的思想写的·· 在DAO中的方法为: (使用了动软自动生成代码) 希望对您有所帮助!

  7. mysql慢查询分析工具比较与实战

    00 前言 在进行mysql性能优化的时候,第一个想到的便是查看慢sql. 但是对于慢sql有没有什么好的工具进行分析呢? 推荐两个工具mysqldumpslow及pt-query-digest. m ...

  8. ThinkPHP6.0学习笔记-模型操作

    ThinkPHP模型 模型定义 在app目录下创建Model目录,即可创建模型文件 定义一个和数据库表相匹配的模型 use think\Model; class User extends Model ...

  9. 部署zookeepe高可用集群

                                                                部署zookeepe高可用集群 部署规划 Nno1         192.16 ...

  10. 文件的读写 - open

    #写文件,r路径\n 空格\t 缩进# fan=open(r'C:/Users/demiyangping_v/Desktop/fan.txt','w', encoding='utf-8')# fan. ...