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