【网络编程】——Java实现(8)—— 实践——数据传输Byte

这里是Java网络编程Java Socket编程相关的学习手记。这里按照官方的Java 8 Toturial教程的Custom Networking学习路径,对相关的一些内容进行解读(并不完全,如果有错请联系我,谢谢^ _ ^),同时在学习的过程中加入个人的理解与对代码运行的思考。

下面是整个专栏的文章链接,用于快速的导航。

导言

我们之前的案例中,我们传输时,一次性从socket上读写的数据都是一行string值。现在,我们想要更加精细地对特定基本数据类型的数据的接收与发送进行探讨。

我们所说的特定基本数据类型,指Java中的如下数据类型。

byte bt = 64;
char c = 'b';
int i = 123456;
boolean bool = true;
long l = 12345678;
float f = 12.345f;
double d = 12.345678;

这里我们使用的关键手段为java.nio.ByteBuffer类。

下面先贴出代码,再进行说明:

Server类:

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Inet4Address;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.ByteBuffer;


public class Server {

    public static final int LOCAL_PORT = 23334;
    public static ByteBuffer byteBuffer = null;

    public static void main(String[] args) throws IOException {

        ServerSocket serverSocket = createSocket();

        // 初始化socket的一些属性,参数
        initSocket(serverSocket);

        // bind
        serverSocket.bind(new InetSocketAddress(Inet4Address.getLocalHost(), LOCAL_PORT));

        System.out.println("服务器准备就绪...");
        System.out.println("服务器信息, IP: " + serverSocket.getInetAddress() +
                           ", Port: " + serverSocket.getLocalPort() );

        while(true){

            Socket clientSocket = serverSocket.accept();

            new HandlerRequestSocket(clientSocket).start();

        }
    }

    public static ServerSocket createSocket() throws IOException {
        ServerSocket serverSocket = new ServerSocket();

        return serverSocket;
    }

    public static void initSocket(ServerSocket socket){
        // TODO initialize Socket
    }

    public static class HandlerRequestSocket extends Thread{
        private Socket  clientSocket;

        public HandlerRequestSocket(Socket clientSocket) {
            this.clientSocket = clientSocket;
        }

        @Override
        public void run() {
            super.run();

            System.out.println("新客户端连接, IP: " + clientSocket.getInetAddress() + ", Port: " + clientSocket.getPort());

            try {

                OutputStream out = clientSocket.getOutputStream();
                InputStream in = clientSocket.getInputStream();

                // 创建一个ByteBuffer,并wrap socket接收的数据,
                byte[] buffer = new byte[256];
                int readCount = in.read(buffer);
                getAndPrint(buffer, readCount);

                // 返回数据给客户端,写
                out.write(buffer, 0, readCount);

                out.close();
                in.close();

                System.out.println("客户端退出, IP: " + clientSocket.getInetAddress() +
                        ", Port: " + clientSocket.getPort() );

            } catch (IOException e) {

                e.printStackTrace();

                System.err.println("连接异常...");

            } finally {
                try {
                    clientSocket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

        }
    }


    public static void getAndPrint(byte[] buffer, int readCount){
        byteBuffer = ByteBuffer.wrap(buffer);

        byte bt = byteBuffer.get();
        char c = byteBuffer.getChar();
        int i = byteBuffer.getInt();
        boolean bool = (byteBuffer.get() == 1 ? true : false);
        long l = byteBuffer.getLong();
        float f = byteBuffer.getFloat();
        double d = byteBuffer.getDouble();

        int pos = byteBuffer.position();
        String str = new String(buffer, pos, readCount-pos-1);

        System.out.println("收到数据: " + readCount + "Bytes. All data is followed: \n" +
                "byte: " + bt + "\n" +
                "char: " + c + "\n" +
                "int: " + i + "\n" +
                "bool: " + bool + "\n" +
                "long: " + l + "\n" +
                "float: " + f + "\n" +
                "double: " + d + "\n" +
                "String: " + str + "\n" );
    }

}

Server类的总体代码框架为main中的代码:

public static void main(String[] args) throws IOException {

        ServerSocket serverSocket = createSocket();

        // 初始化socket的一些属性,参数
        initSocket(serverSocket);

        // bind
        serverSocket.bind(new InetSocketAddress(Inet4Address.getLocalHost(), LOCAL_PORT));

        System.out.println("服务器准备就绪...");
        System.out.println("服务器信息, IP: " + serverSocket.getInetAddress() +
                           ", Port: " + serverSocket.getLocalPort() );

        while(true){

            Socket clientSocket = serverSocket.accept();

            new HandlerRequestSocket(clientSocket).start();

        }
    }

先实例化一个ServerSocket,再初始化此ServerSocket:initSocket(serverSocket);函数为空,只是示意一下代码框架)。然后对socket进行绑定操作。接着一个while循环处理接收的数据。本文章主要的内容在getAndPrint函数部分。
现在先不说明其作用,待下面我们将客户端的程序代码列出来之后,一起讲。

下面是Client类:

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Inet4Address;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.nio.ByteBuffer;


public class Client {

    public static final int LOCAL_PORT = 23333;
    public static final int REMOTE_PORT = 23334;

    public static ByteBuffer byteBuffer = null;

    public static void main(String[] args) throws IOException {

        Socket socket = createSocket();

        initSocket(socket);

        socket.connect(new InetSocketAddress(Inet4Address.getLocalHost(), REMOTE_PORT), 3000);

        System.out.println("发起服务器连接...");
        System.out.println("服务器信息, IP: " + Inet4Address.getLocalHost() + ", Port: " + REMOTE_PORT);
        System.out.println("客户端信息, IP: " + Inet4Address.getLocalHost() + ", Port: " + LOCAL_PORT);

        requestSocket(socket);


        socket.close();
        System.out.println("客户端退出...");
    }

    public static Socket createSocket() throws IOException {

        Socket socket = new Socket();

        socket.bind(new InetSocketAddress(Inet4Address.getLocalHost(), LOCAL_PORT));

        return socket;

    }

    public static void initSocket(Socket socket){
        // TODO initialize Socket
    }

    public static void requestSocket(Socket socket) throws IOException {

        // to read
        InputStream input = socket.getInputStream();
        // to write
        OutputStream out = socket.getOutputStream();

        // 将buffer放到ByteBuffer里
        byte[] buffer = new byte[256];
        putByteBufferData(buffer);

        // 发送信息,写socket
        out.write(buffer, 0, byteBuffer.position()+1);


        System.out.println("发送数据成功...");

        out.close();
        input.close();
    }

    public static void putByteBufferData(byte[] buffer){

        // 发送不同类型的数据
        byte bt = 64;
        char c = 'b';
        int i = 123456;
        boolean bool = true;
        long l = 12345678;
        float f = 12.345f;
        double d = 12.345678;
        String str = "test测试";

        // 将buffer放到ByteBuffer里
        byteBuffer = ByteBuffer.wrap(buffer);

        byteBuffer.put(bt);
        byteBuffer.putChar(c);
        byteBuffer.putInt(i);
        byteBuffer.put(bool ? (byte) 1 : (byte)0);
        byteBuffer.putLong(l);
        byteBuffer.putFloat(f);
        byteBuffer.putDouble(d);
        byteBuffer.put(str.getBytes());

    }

}

同样,对Server类的框架理解了,这里的代码框架了同样理解了。

下面说明ByteBuffer对基本数据类型的发送的实现。

我们使用ByteBuffer时,一般不会将socket获得的InputStream,OutputStream进行封装获取BufferedReader等高级的输入输出类对象。我们直接使用InputStream,OutputStream

一般性的操作:
byte[] buffer = new byte[256];
ByteBuffer byteBuffer = ByteBuffer.wrap(buffer);
byteBuffer.putXX();
或者
byteBuffer.getXX()

XX代码前面我们所列举的基本数据类型。
如果XX为空,那么就是byteBuffer.put()或byteBuffer.get()直接放入/获取一个byte的数据

很容易理解。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值