socket網絡編程登陸實現及多客戶端和服務端的數據交互

一.TCP/IPjava

客戶端編程

package com.demo.entity; import java.io.Serializable; public class UserInfo implements Serializable { /** * */
    private static final long serialVersionUID = 1L; /** * */
    private String username; private String password; public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } }

 

package com.demo.entity; import java.io.BufferedInputStream; import java.io.ObjectOutputStream; import java.net.Socket; import java.util.Scanner; public class UserClient { private static int port = 5566; private static String host = "localhost"; public static void main(String[] args) { Socket socket =  null; // 建立掃描器對象
        Scanner sc = null; try { sc = new Scanner(System.in); // 建立一個客戶端的Socket對象,獲取服務端輸入和輸出流對象
            socket = new Socket(host, port); ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream()); System.out.println("請輸入帳號:"); String userName = sc.nextLine(); System.out.println("請輸入密碼:"); String password = sc.nextLine(); // 封裝一個用戶對象
            UserInfo user = new UserInfo(); user.setPassword(password); user.setUsername(userName); // 序列化到輸出流中
 oos.writeObject(user); // 釋放流資源
 oos.flush(); // 讀取從服務端返回的數據
            BufferedInputStream bis = new BufferedInputStream(socket.getInputStream()); byte[] buffer = new byte[1024]; int len = 0; while ((len = bis.read(buffer)) != -1) { String content = new String(buffer, 0, len); System.out.println("登陸結果:"+content); } socket.shutdownOutput(); socket.shutdownInput(); } catch (Exception e) { e.printStackTrace(); } finally { try { if (socket != null) { socket.close(); } } catch (Exception e2) { e2.printStackTrace(); } sc.close(); } } }

服務器端數組

package com.demo.entity; import java.io.Serializable; public class UserInfo implements Serializable { /** * */
    private static final long serialVersionUID = 1L; /** * */
    private String username; private String password; public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } }

 

package com.demo.entity; import java.io.BufferedOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.net.ServerSocket; import java.net.Socket; /** * 一、服務器端序列化的對象全名稱必須和反序列化的全名稱徹底一致 * 二、序列化和反序列化對象的序列化Id必須一致 * 三、在網絡編程中須要在網絡中傳輸對象必須實現Serializable。 * 四、釋放資源的時候流不要使用close方法關閉。 * @author Administrator * */
public class UserServer { private static int port = 5566; public static void main(String[] args) { ServerSocket serverSocket = null; Socket socket = null; while (true) { try { serverSocket = new ServerSocket(port); System.out.println("等待客戶端鏈接"); // 服務器socket, 能夠獲取到客戶端對應輸入流和輸出流對象
                socket = serverSocket.accept(); System.out.println("端口號:"+socket.getPort()); System.out.println(socket.getInetAddress().getCanonicalHostName() + "鏈接到了服務器"); // 建立一個反序列化流
                ObjectInputStream ois = new ObjectInputStream(socket.getInputStream()); // 返回客戶端序列化的對象
                UserInfo user = (UserInfo) ois.readObject(); System.out.println(user.getPassword() + "---" + user.getUsername()); // 獲取帳號和密碼
                String account = user.getUsername(); String password = user.getPassword(); // 建立輸出流
                BufferedOutputStream bos = new BufferedOutputStream(socket.getOutputStream()); // 判斷轉換和密碼是否正確
                if ("admin".equals(account) && "123".equals(password)) { bos.write("登陸成功".getBytes()); } else { bos.write("登陸失敗".getBytes()); } bos.flush(); bos.close(); ois.close(); } catch (Exception e) { e.printStackTrace(); } finally { try { if (serverSocket != null) { serverSocket.close(); } } catch (IOException e) { e.printStackTrace(); } } } } }

 

package com.demo.entity; import java.io.BufferedOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.net.ServerSocket; import java.net.Socket; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; /** * 一、服務器端序列化的對象全名稱必須和反序列化的全名稱徹底一致 * 二、序列化和反序列化對象的序列化Id必須一致 * 三、在網絡編程中須要在網絡中傳輸對象必須實現Serializable。 * 四、釋放資源的時候流不要使用close方法關閉。 * @author Administrator * */
public class UserServerM { private static int port = 5555; public static void main(String[] args) throws IOException { int clientNo = 1; ServerSocket serverSocket = new ServerSocket(port); // 建立一個緩存線程池
        ExecutorService pool = Executors.newCachedThreadPool(); try { while (true) { Socket socket = serverSocket.accept(); pool.execute(new SingleServer(clientNo++, socket)); } } catch (Exception e) { e.printStackTrace(); } finally { pool.shutdown(); if (!serverSocket.isClosed()) { serverSocket.close(); } } } } class SingleServer  implements Runnable { private int clientNo; // 客戶端編號
    private Socket socket; public SingleServer(int clientNo, Socket socket) { this.clientNo = clientNo; this.socket = socket; } @Override public void run() { System.out.println("第"+clientNo+"客戶端鏈接到了服務器"); System.out.println("port:"+socket.getPort()); System.out.println(socket.getInetAddress().getCanonicalHostName() + "鏈接到了服務器"); try { // 建立一個反序列化流
            ObjectInputStream ois = new ObjectInputStream(socket.getInputStream()); // 返回客戶端序列化的對象
            UserInfo user = (UserInfo) ois.readObject(); System.out.println(user.getPassword() + "---" + user.getUsername()); // 獲取帳號和密碼
            String account = user.getUsername(); String password = user.getPassword(); // 建立輸出流
            BufferedOutputStream bos = new BufferedOutputStream(socket.getOutputStream()); // 判斷轉換和密碼是否正確
            if ("admin".equals(account) && "123".equals(password)) { bos.write("登陸成功".getBytes()); } else { bos.write("登陸失敗".getBytes()); } bos.flush(); bos.close(); ois.close(); } catch (Exception e) { e.printStackTrace(); } finally { try { if (!socket.isConnected()) { socket.close(); } } catch (Exception e2) { e2.printStackTrace(); } } } }

 二.UDP緩存

import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; /* * 客戶端 */
public class UDPClient { public static void main(String[] args) throws IOException { /* * 向服務器端發送數據 */
        // 1.定義服務器的地址、端口號、數據
        InetAddress address = InetAddress.getByName("localhost"); int port = 8800; byte[] data = "用戶名:admin;密碼:123".getBytes(); // 2.建立數據報,包含發送的數據信息
        DatagramPacket packet = new DatagramPacket(data, data.length, address, port); // 3.建立DatagramSocket對象
        DatagramSocket socket = new DatagramSocket(); // 4.向服務器端發送數據報
 socket.send(packet); /* * 接收服務器端響應的數據 */
        // 1.建立數據報,用於接收服務器端響應的數據
        byte[] data2 = new byte[1024]; DatagramPacket packet2 = new DatagramPacket(data2, data2.length); // 2.接收服務器響應的數據
 socket.receive(packet2); // 3.讀取數據
        String reply = new String(data2, 0, packet2.getLength()); System.out.println("我是客戶端,服務器說:" + reply); // 4.關閉資源
 socket.close(); } }

 

import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; /* * 服務器端,實現基於UDP的用戶登錄 */
public class UDPServer { public static void main(String[] args) throws IOException { /* * 接收客戶端發送的數據 */
        // 1.建立服務器端DatagramSocket,指定端口
        DatagramSocket socket = new DatagramSocket(8800); // 2.建立數據報,用於接收客戶端發送的數據
        byte[] data = new byte[1024];// 建立字節數組,指定接收的數據包的大小
        DatagramPacket packet = new DatagramPacket(data, data.length); // 3.接收客戶端發送的數據
        System.out.println("****服務器端已經啓動,等待客戶端發送數據"); socket.receive(packet);// 此方法在接收到數據報以前會一直阻塞 // 4.讀取數據
        String info = new String(data, 0, packet.getLength()); System.out.println("我是服務器,客戶端說:" + info); /* * 向客戶端響應數據 */
        // 1.定義客戶端的地址、端口號、數據
        InetAddress address = packet.getAddress(); int port = packet.getPort(); byte[] data2 = "歡迎您!".getBytes(); // 2.建立數據報,包含響應的數據信息
        DatagramPacket packet2 = new DatagramPacket(data2, data2.length, address, port); // 3.響應客戶端
 socket.send(packet2); // 4.關閉資源
 socket.close(); } }
相關文章
相關標籤/搜索