首先我們需要客戶端和服務器端。
服務器端需要: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類,包也要是一樣的。里面的內容就是拷貝的。
運行截圖:因為是多線程所以可以多啟動幾次客戶端,進行模仿多用戶登錄