首先我们需要客户端和服务器端。

服务器端需要:1.创建ServerSocket对象。2.监听客户端的请求数据。3.获取输入流(对象流)即用户在客户端所发过来的信息。                               4.创建用户对象。5.判断用户信息是否正确。6.获取输出端,反馈用户信息。9.关闭流。

客户端需要:1.创建Socket对象。2.获取输出流(对象流)。3.创建用户对象,并且赋值。4.将用户数据发送给服务器端。5.获取输入                            流,用来接收服务器端返回的数据。6.关闭流。

我们将用户的信息序列化,因此次在服务器接收数据时,需要反序列化。

User类:

package com.bjsxt.entity;

import java.io.Serializable;

public class User implements Serializable{
/**
*
*/
private static final long serialVersionUID = -3217779599604368894L;
private String name;
private String password;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public User(String name, String password) {
super();
this.name = name;
this.password = password;
}
public User() {
super();
} }

Client类:

package com.bjsxt.entity;

import java.io.DataInputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Scanner; public class Client {
public static void main(String[] args) throws UnknownHostException, IOException {
//1.创建socket对象,用于连接服务器
Socket client=new Socket("192.168.41.29", 8888);
//2.获取输出流(对象流)
ObjectOutputStream oos= new ObjectOutputStream(client.getOutputStream());
//3.创建user对象(调用获取对象的方法)
User u=getUser();
//4.将user对象发送到服务器中
oos.writeObject(u);
//5.获取输入流(数据流)
DataInputStream dis=new DataInputStream(client.getInputStream());
System.out.println(dis.readUTF());
//6.关闭流,关闭socket
if (dis!=null) {
dis.close();
} if (oos!=null) {
oos.close();
} if (client!=null) {
client.close();
}
}
public static User getUser() {
Scanner input=new Scanner(System.in);
System.out.println("请输入用户名:");
String name = input.next();
System.out.println("请输入密码:");
String password = input.next(); return new User(name, password); }
}

Server类:

package com.bjsxt.server;

import java.io.DataOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.net.ServerSocket;
import java.net.Socket; import com.bjsxt.entity.User;
import com.bjsxt.thread.ServerThread; public class Server {
public static void main(String[] args) throws IOException, ClassNotFoundException {
System.out.println("--------------服务器已启动,等待客户端连接---------------");
//1.创建ServerSocket对象
ServerSocket server=new ServerSocket(8888); while (true) {
//2.监听客户端的请求
Socket socket = server.accept();
ServerThread st=new ServerThread(socket);
new Thread(st).start();
} }
}

ServerThread类(为了实现多线程,很多客户端访问同一个服务器端。)

package com.bjsxt.thread;

import java.io.DataOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.net.Socket; import com.bjsxt.entity.User; public class ServerThread implements Runnable{
private Socket socket;//成员变量
public ServerThread(Socket socke) {
this.socket=socke;
}
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"请求登录。");
//3.获取输入流(对象流)
ObjectInputStream ois=null;
//5.获取输出流(数据流),反馈给客户端登录信息
DataOutputStream dos=null;
try {
ois = new ObjectInputStream(socket.getInputStream());
User user =(User) ois.readObject();
System.out.println(socket.getInetAddress().getHostAddress()+"请求登录\t用户名:"+user.getName()+"\t密码:"+user.getPassword());
String str="";
//4.对用户名和密码进行验证
if ("yxf".equals(user.getName())&&"123".equals(user.getPassword())) {
str=user.getName()+"登录成功!";
}else {
str="登录失败!账号或密码有误!";
}
dos = new DataOutputStream(socket.getOutputStream());
dos.writeUTF(str);
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//6.关闭流,
if (dos!=null) {
try {
dos.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} if (ois!=null) {
try {
ois.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} if (socket!=null) {
try {
socket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} } }

项目工程截图:

说明:由于User类是序列化 的,因此我们需要在/serverLoginProject项目中建立一个一模一样的User类,包也要是一样的。里面的内容就是拷贝的。

运行截图:因为是多线程所以可以多启动几次客户端,进行模仿多用户登录

Java修炼——基于TCP协议的Socket编程_双向通信_实现模拟用户登录的更多相关文章

  1. Java:基于TCP协议网络socket编程(实现C/S通信)

    目录 一.前言:TCP原理简介 二.Socket编程通信 三.TCP服务器端(具体代码) 四.TCP客户端(具体代码) 五.通信效果演示 六."创意"机器人:价值一个亿的AI核心代 ...

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

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

  3. 基于TCP协议的socket编程

    什么是socket Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口.在设计模式中,Socket其实就是一个门面模式,它把复杂的TCP/IP协议族隐藏在Socket接口后面, ...

  4. 基于TCP协议之socket编程

    #服务端 #导入一个socket模块 import socket #想象成买手机打电话:socket.SOCK_STREAM 表示建立tcp连接 ,udp连接socket.SOCK_DGRAM #买了 ...

  5. 基于TCP/UDP的socket编程

    基于TCP(面向连接)的socket编程服务器端顺序: 1. 创建套接字(socket) 2. 将套接字绑定到一个本地地址和端口上(bind) 3. 将套接字设为监听模式,准备接收客户请求(liste ...

  6. 基于TCP(面向连接)的Socket编程

    基于TCP(面向连接)的Socket编程 一.客户端: 1.打开一个套接字(Socket); 2.发起连接请求(connect); 3.如果连接成功,则进行数据交换(read.write.send.r ...

  7. 基于TCP 协议的socket 简单通信

    DNS 服务器:域名解析 socket 套接字 : ​ socket 是处于应用层与传输层之间的抽象层,也是一组操作起来非常简单的接口(接受数据),此接口接受数据之后,交由操作系统 为什么存在 soc ...

  8. (4)socket的基础使用(基于TCP协议的并发编程)

    需要实现并发需要依靠socketserver 模块 socketserver模块下有几个功能 def __init__(self, request, client_address, server): ...

  9. 基于TCP协议的socket套接字编程

    目录 一.什么是Scoket 二.套接字发展史及分类 2.1 基于文件类型的套接字家族 2.2 基于网络类型的套接字家族 三.套接字工作流程 3.1 服务端套接字函数 3.2 客户端套接字函数 3.3 ...

随机推荐

  1. introduce new products

    Today's the day. I'm giving you the heads up. Our company is rolling up its new line of cell phones. ...

  2. 深入理解计算机系统 第八章 异常控制流 part1

    本章主旨 第八章的目的是阐述清楚应用程序是如何与操作系统交互的(之前章节的学习是阐述应用程序是如何与硬件交互的) 异常控制流 异常控制流,即 ECF(exceptional contril flow) ...

  3. 爬虫多线程模板,xpath,etree

    class QuiShi: def __init__(self): self.temp_url = "http://www.lovehhy.net/Joke/Detail/QSBK/{0}& ...

  4. 反汇编分析objc函数枢纽objc_msgSend

    在分析objc_msgSend之前,先来搞清楚另一个问题. 函数是什么?可能会答 void foo(void) {} 像这样就是一个函数.或者函数包括函数原型和函数定义,是一段执行某样功能的机器代码. ...

  5. firefox浏览器中使用vux的x-input报错TypeError: _this3.$refs.input.scrollIntoViewIfNeeded is not a function

    最近做公众号项目,想着统一风格,所以决定使用vux. 在调试时发现,只要鼠标点击x-input输入框,就会报错 TypeError: _this3.$refs.input.scrollIntoView ...

  6. 编写自定义cmake配置文件FindXXX.cmake或者xxx-config.cmake | cmake with user defined entry

    本文首发于个人博客https://kezunlin.me/post/12ab5707/,欢迎阅读! cmake with user defined entry Guide FindXXX.cmake ...

  7. 以太网驱动的流程浅析(一)-Ifconfig主要流程【原创】

    以太网驱动的流程浅析(一)-Ifconfig主要流程 Author:张昺华 Email:920052390@qq.com Time:2019年3月23日星期六 此文也在我的个人公众号以及<Lin ...

  8. Android 获取 SHA1值3步完成

    未经允许,禁止

  9. Netflix 开源 Polynote:对标 Jupyter,一个笔记本运行多种语言

    谈到数据科学领域的开发工具,Jupyter 无疑是非常知名的一种.它具有灵活高效的特点,非常适合进行开发.调试.分享和教学.近日,Netflix(奈飞)居然也玩起了跨界,他们开源了一个名为 Polyn ...

  10. pwnable.kr第二天

    3.bof 这题就是简单的数组越界覆盖,直接用gdb 调试出偏移就ok from pwn import * context.log_level='debug' payload='A'*52+p32(0 ...