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


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

服务器端需要: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类,包也要是一样的。里面的内容就是拷贝的。

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


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM