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

2022-11-22,,,,

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

服务器端需要: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编程_双向通信_实现模拟用户登录的相关教程结束。

《Java修炼——基于TCP协议的Socket编程_双向通信_实现模拟用户登录.doc》

下载本文的Word格式文档,以方便收藏与打印。