java socket之传输实体类对象

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java socket之传输实体类对象相关的知识,希望对你有一定的参考价值。

一、TCP编程

    TCP协议是面向连接的、可靠地、有序的,以字节流的方式发送数据。java实现TCP通信依靠2个类:客户端的Socket类和服务器端的ServerSocket类。

技术分享

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

技术分享

 

技术分享

    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();
        }
    }
}

 

 

技术分享

技术分享

以上是关于java socket之传输实体类对象的主要内容,如果未能解决你的问题,请参考以下文章

JAVA中,类、对象、实体、实体类、实体对象之间存在怎样的联系??请高手做形象的解释。

java 25 - 4 网络编程之 UDP协议传输思路

Java Socket实战之六 使用NIO包实现Socket通信

Java NIO之通道

Java NIO之通道

Java 网络编程 之 TCP协议