免费视频淫片aa毛片_日韩高清在线亚洲专区vr_日韩大片免费观看视频播放_亚洲欧美国产精品完整版

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
JavaSocket短連接實現(xiàn)分別接收字符串和16進制數(shù)據(jù)

做個筆記,在接收16進制數(shù)據(jù)的時候亂碼了。原因是Socket在接收數(shù)據(jù)的時候需要根據(jù)不同的數(shù)據(jù)定義不同的接收方式,也就是約定好傳輸協(xié)議(具體體現(xiàn)在后面服務(wù)端接收16進制那里)。

字符串的發(fā)送接收

字符串發(fā)送:

字符串接收:

客戶端代碼:

沒什么好說的,復(fù)制粘貼導(dǎo)包。

public static void main(String[] args)    {        try        {            Socket socket = new Socket("localhost", 8888);            //得到一個輸出流,用于向服務(wù)器發(fā)送數(shù)據(jù)            OutputStream outputStream = socket.getOutputStream();            //將寫入的字符編碼成字節(jié)后寫入一個字節(jié)流            OutputStreamWriter writer = new OutputStreamWriter(outputStream, "UTF-8");            System.out.println("請輸入數(shù)據(jù):");            while (true)            {				Scanner sc = new Scanner(System.in);                String data = sc.nextLine();                writer.write(data);                //刷新緩沖                writer.flush();                //只關(guān)閉輸出流而不關(guān)閉連接                socket.shutdownOutput();                //獲取服務(wù)器端的響應(yīng)數(shù)據(jù)                //得到一個輸入流,用于接收服務(wù)器響應(yīng)的數(shù)據(jù)                InputStream inputStream = socket.getInputStream();                //字節(jié)流以UTF-8的編碼轉(zhuǎn)換為字符流                InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "UTF-8");                //為輸入流添加緩沖                BufferedReader bufferedReader = new BufferedReader(inputStreamReader);                System.out.println("客戶端IP地址:"   socket.getInetAddress().getHostAddress());                String info;                //輸出服務(wù)器端響應(yīng)數(shù)據(jù)                while ((info = bufferedReader.readLine()) != null)                {                    System.out.println("收到來自服務(wù)端的信息:"   info);                }                //關(guān)閉資源                bufferedReader.close();                inputStreamReader.close();                inputStream.close();                writer.close();                outputStream.close();                socket.close();            }        }        catch (IOException e)        {            e.printStackTrace();        }    }

服務(wù)端代碼:

注意readLine()方法,客戶端發(fā)送的內(nèi)容結(jié)尾一定要有換行符,不然會一直阻塞導(dǎo)致客戶端得不到響應(yīng)。其它注釋里都有。

try        {            System.out.println(">>>服務(wù)啟動,等待終端的連接\n");            ServerSocket server = new ServerSocket(8888);            int count = 0;            while (true)            {                //開啟監(jiān)聽                Socket socket = server.accept();                count  ;                System.out.println(">>>第"   count   "個終端連接成功");                ServerThread thread = new ServerThread(socket);                thread.start();            }        }        catch (IOException e)        {            e.printStackTrace();        }
/** * 短連接 */public class ServerThread extends Thread{    private Socket m_socket;    public ServerThread(Socket socket)    {        this.m_socket = socket;    }    @Override    public void run()    {        //字節(jié)輸入流        InputStream inputStream = null;        //字節(jié)輸出流        OutputStream outputStream = null;        //字節(jié)輸入流到字符輸入流的轉(zhuǎn)換        InputStreamReader inputStreamReader = null;        //加快字符讀取速度        BufferedReader bufferedReader = null;        //打印輸出流        PrintWriter printWriter = null;        try        {            inputStream = m_socket.getInputStream();            String info;            inputStreamReader = new InputStreamReader(inputStream);            bufferedReader = new BufferedReader(inputStreamReader);            //注意,readLine()方法如果沒有讀到報文結(jié)束符(換行)會一直阻塞            while ((info = bufferedReader.readLine()) != null)            {                System.out.println(">>>線程"   this.getId()   "收到來自終端的信息:"   info);            }            //關(guān)閉終端的輸入流(不關(guān)閉服務(wù)端的輸出流),此時m_socket雖然沒有關(guān)閉,但是客戶端已經(jīng)不能再發(fā)送消息            m_socket.shutdownInput();            //解析終端的信息            String responseStr = "Null...";            if (null != info && !"".equals(info))            {                //模擬業(yè)務(wù)處理Thread.sleep(10000);                responseStr = new MessageReceive().RecevieHexStr(info);            }            outputStream = m_socket.getOutputStream();            printWriter = new PrintWriter(outputStream);            printWriter.write(responseStr);            printWriter.flush();        }        catch (Exception e)        {            e.printStackTrace();        }        //關(guān)閉資源        finally        {            System.out.println(">>>本次連接已斷開\n");            try            {                if (printWriter != null)                    printWriter.close();                if (outputStream != null)                    outputStream.close();                if (bufferedReader != null)                    bufferedReader.close();                if (inputStreamReader != null)                    inputStreamReader.close();                if (inputStream != null)                    inputStream.close();                if (m_socket != null)                    m_socket.close();            }            catch (IOException e)            {                e.printStackTrace();            }        }    }}

?16進制數(shù)據(jù)的發(fā)送接收

客戶端代碼:無

由Socket測試工具來完成,網(wǎng)上大把,自行下載。

服務(wù)端代碼:

開頭說過使用Socket通信需要約定好協(xié)議,否則服務(wù)端不知道你客戶端內(nèi)容是否發(fā)送完畢,就會一直阻塞。前面的字符串的發(fā)送和接收其實也是有協(xié)議存在的,這個協(xié)議就是字符串和換行符,服務(wù)端讀取的時候?qū)⒆止?jié)流轉(zhuǎn)為字符流,然后一行行的讀取,讀到換行符的時候就表示客戶端的消息已發(fā)送完畢。

但是當(dāng)客戶端發(fā)送的是16進制數(shù)據(jù)的時候,這個時候服務(wù)端仍然用讀取字符串的方式去處理就會亂碼。所以這里采用的方法是將字節(jié)流以字節(jié)的形式一個一個的讀出來,然后每個字節(jié)轉(zhuǎn)為16進制的字符串。

byte[] bytes = new byte[1];while ((dataInputStream.read(bytes)) != -1)    String tempStr = ConvertUtil.ByteArrayToHexStr(bytes);

同理,也需要一個標(biāo)識符表示客戶端的內(nèi)容已經(jīng)發(fā)送完畢,否則read()方法也會一直阻塞,導(dǎo)致客戶端得不到響應(yīng)。比如客戶端發(fā)送內(nèi)容的末尾加個7E,當(dāng)服務(wù)端讀到7E就跳出While循環(huán),但前提是要保證發(fā)送內(nèi)容里面7E是唯一的,如果有其它需要用7E表示的自行轉(zhuǎn)義,然后服務(wù)端讀取完內(nèi)容以后再轉(zhuǎn)義回來。

這里我使用的是另外一種方法判斷客戶端的內(nèi)容是否發(fā)送完畢:InputStream對象的available()方法。

dataInputStream.available()

官方解釋:返回此輸入流下一個方法調(diào)用可以不受阻塞地從此輸入流讀取(或跳過)的估計字節(jié)數(shù)。下一個調(diào)用可能是同一個線程,也可能是另一個線程。一次讀取或跳過此估計數(shù)個字節(jié)不會受阻塞,但讀取或跳過的字節(jié)數(shù)可能小于該數(shù)。大白話就是:返回剩余未讀長度

至于其它的注釋里都有寫

/** * 短連接 */public class ServerThread extends Thread{    private Socket m_socket;    public ServerThread(Socket socket)    {        this.m_socket = socket;    }    @Override    public void run()    {        //字節(jié)輸入流        InputStream inputStream = null;        //字節(jié)輸出流        OutputStream outputStream = null;        //緩沖輸入流        BufferedInputStream bufferedInputStream = null;        //數(shù)據(jù)輸入流        DataInputStream dataInputStream = null;        //打印輸出流        PrintWriter printWriter = null;        try        {            inputStream = m_socket.getInputStream();            String info = "";            bufferedInputStream = new BufferedInputStream(inputStream);            dataInputStream = new DataInputStream(bufferedInputStream);            //一次讀取一個byte            byte[] bytes = new byte[1];            //注意,read()方法如果沒有數(shù)據(jù)會一直阻塞,也就是永遠(yuǎn)不會等于-1,除非客戶端調(diào)用close(),如果想在while循環(huán)外部獲取數(shù)據(jù)則需要設(shè)定跳出條件            while ((dataInputStream.read(bytes)) != -1)            {                String tempStr = ConvertUtil.ByteArrayToHexStr(bytes)   " ";                info  = tempStr;                //返回下次調(diào)用可以不受阻塞地從此流讀取或跳過的估計字節(jié)數(shù),如果等于0則表示已經(jīng)讀完                if (dataInputStream.available() == 0)                {                    System.out.println(">>>終端信息讀取完畢,最后一位:"   tempStr);                    break;                }            }            System.out.println(">>>線程"   this.getId()   "收到來自終端的信息:"   info);            //關(guān)閉終端的輸入流(不關(guān)閉服務(wù)端的輸出流),此時m_socket雖然沒有關(guān)閉,但是客戶端已經(jīng)不能再發(fā)送消息            m_socket.shutdownInput();            //解析終端的信息            String responseStr = "Null...";            //模擬業(yè)務(wù)處理            Thread.sleep(10000);            outputStream = m_socket.getOutputStream();            printWriter = new PrintWriter(outputStream);            printWriter.write(responseStr);            printWriter.flush();        }        catch (Exception e)        {            e.printStackTrace();        }        //關(guān)閉資源        finally        {            System.out.println(">>>本次連接已斷開\n");            try            {                if (printWriter != null)                    printWriter.close();                if (outputStream != null)                    outputStream.close();                if (inputStream != null)                    inputStream.close();                if (bufferedInputStream != null)                    bufferedInputStream.close();                if (dataInputStream != null)                    dataInputStream.close();                if (m_socket != null)                    m_socket.close();            }            catch (IOException e)            {                e.printStackTrace();            }        }    }}
自定義的轉(zhuǎn)換類:
/**     * 普通byte[]轉(zhuǎn)16進制Str     *     * @param array     */    public static String ByteArrayToHexStr(byte[] array)    {        StringBuilder stringBuilder = new StringBuilder();        for (int i = 0; i < array.length; i  )        {            String hex = Integer.toHexString(array[i] & 0xFF);            if (hex.length() == 1)            {                stringBuilder.append("0");            }            stringBuilder.append(hex);        }        return stringBuilder.toString();    }

?

來源:https://www.icode9.com/content-1-373801.html
本站僅提供存儲服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊舉報。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
原來BufferedReader不能和InputStream交替使用
用Socket做一個通訊項目的一點心得
基于Tcp協(xié)議的簡單Socket通信實例(JAVA)
Java實現(xiàn)簡單的Socket服務(wù)器與客戶端字符串通訊(適合初學(xué)者閱讀)
JAVA:IO流 之 節(jié)點流與處理流(2)
實現(xiàn)server和client模型程序
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點擊這里聯(lián)系客服!

聯(lián)系客服