java socket之傳輸實體類對象


一、TCP編程

    TCP協議是面向連接的、可靠地、有序的,以字節流的方式發送數據。java實現TCP通信依靠2個類:客戶端的Socket類和服務器端的ServerSocket類。

54d2c4680001724104240149.jpg

基於TCP通信的Socket模型如下:

 

54d2c4ce00012bbe05000321.jpg

    Socket通信的實現步驟如下:

1.    創建服務器端Socket:ServerSocket和客戶端Socket:Socket;

2.    打開連接到Socket的InputStream/OutputStream;

3.    按照協議對Socket進行讀寫操作;

4.    關閉InputStream和OutputStream和Socket。

下面是一個例子:實現功能是,客戶端向服務端發送一個User類實體對象,服務端每接收到一個請求便開啟一個處理線程將用戶信息打印出來,並向客戶端發送“歡迎登錄”。

1)工程結構

2)服務端和客戶端信息交流類:User

為了能實現傳輸。客戶端和服務端的User類的包結構要一樣,該類必須要序列化

User類

package com.model;
import java.io.Serializable;
 
public class User implements Serializable {
    private int id;
    private String name;
    private String password;
 
    public User(int id, String name, String password) {
    super();
    this.id = id;
    this.name = name;
    this.password = password;
    }
 
    @Override
    public String toString() {
    return "User [id=" + id + ", name=" + name + ", password=" + password+ "]";
    }
 
}

3)服務端

simpleServer類,主要是用於接受請求並開起處理線程

package simpleSocketServer;

import java.io.IOException;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;

public class simpleServer {

    public static void main(String[] args){
        try {
            ServerSocket serverSocket = new ServerSocket(9999);
            int count = 0;// 記錄客戶端的數量
            System.out.println("服務器啟動,等待客戶端的連接。。。");
            Socket socket = null;
            while(true){
                socket=serverSocket.accept();
                ++count;
                Thread serverHandleThread=new Thread(new ServerHandleThread(socket));
                serverHandleThread.setPriority(4);
                serverHandleThread.start();
                System.out.println("上線的客戶端有" + count + "個!");
                InetAddress inetAddress = socket.getInetAddress();
                System.out.println("當前客戶端的IP地址是:"+inetAddress.getHostAddress());
            }
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

ServerHandleThread,服務器對socket進行處理的線程

package simpleSocketServer;

import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;

import com.model.User;

public class ServerHandleThread implements Runnable{
    Socket socket=null;
     
    public ServerHandleThread(Socket socket) {
        super();
        this.socket = socket;
    }
    @Override
    public void run() {
        // TODO Auto-generated method stub
        OutputStream os = null;
        PrintWriter pw = null;
        try {
            InputStream is = socket.getInputStream();
            ObjectInputStream ois=new ObjectInputStream(is);
            //readObject()方法必須保證服務端和客戶端的User包名一致,要不然會出現找不到類的錯誤
            System.out.println("客戶端發送的對象:" + (User) ois.readObject());
            socket.shutdownInput();// 禁用套接字的輸入流
            os=socket.getOutputStream();
            pw=new PrintWriter(os);
            pw.println("歡迎登錄!");
            pw.flush();
            socket.shutdownOutput();
            
        } catch (IOException | ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }finally{
            try{
                if(pw!=null){
                    pw.close();
                }
                if(os!=null){
                    os.close();
                }
                if(socket!=null){
                    socket.close();
                }
            }catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
            }

        }
    }
    
} 

4)客戶端

package simpleSocketClient;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
import java.nio.file.attribute.UserPrincipalNotFoundException;

import javax.sound.midi.MidiDevice.Info;

import com.model.User;

/**
 * 基於TCP協議的Socket通信,實現用戶登錄-客戶端
 */
public class Client {
 
    public static void main(String[] args) {
        // 1.創建客戶端的Socket,指定服務器的IP和端口
        try {
            Socket socket = new Socket("127.0.0.1", 9999);
             
            // 2.獲取該Socket的輸出流,用來向服務器發送信息
            OutputStream os = socket.getOutputStream();
            ObjectOutputStream oos = new ObjectOutputStream(os);
            oos.writeObject(new User(1, "root", "123456"));
            socket.shutdownOutput();
            String infoString=null;
            
            // 3.獲取輸入流,取得服務器的信息
            InputStream is = socket.getInputStream();
            BufferedReader br=new BufferedReader(new InputStreamReader(is));
            String info=null;
            while((info=br.readLine())!=null){
                System.out.println("服務器端的信息:" + info);
            }
            socket.shutdownInput();
            oos.close();
            os.close();
            is.close();
            br.close();
            socket.close();
        } catch (UnknownHostException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

 

 

54d2ca0c000180eb05000258.jpg

54d2ca240001a14905000208.jpg


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM