Socket,IO(一)

来源:互联网 发布:淘宝满包邮在哪里设置 编辑:程序博客网 时间:2024/06/08 03:39

      • 初识socket简单创简单你server连接
      • 使用DataInputStream和DataOutputStream流传输
      • 使用InputStream和OutputStream传输

初识socket简单创简单你server连接

基于tcp协议,建立稳定性连接的点对点通信。
实时、快速。安全性高、占用系统资源多。效率低
“请求-响应” 模式
客户端:在网络通讯中,第一次主动发起通讯的程序被称作客户端(client)程序
服务器:第一次通讯中等待连接的程序被称作服务器端(Server)程序
Socket:发送TCP消息
ServerSocket:创建服务器
套接字:是一种进程间的数据交换机制。这些进程既可以在同一机器上,也可以在网络连接的不通机器上
换句话说,套接字起到通信端点的作用。单个套接字是一个端点,而一对套接字则构成了一个双向通信信道
使非关联进程可以在本地或通过网络进行数据交换。一旦建立套接字连接,数据即可在相同或不通的系统中双向或单项发送,
直到其中一个端点关闭连接。

简单的Socket连接
server端:

    public class Server{        public static void main(String[] args) throws IOException {            //1.创建 服务器制定端口            ServerSocket server = new ServerSocket(8888);            //2.接收客户端连接,阻塞式(表示没有客户端接入不会向下运行)            Socket socket = server.accept();            System.out.println("一个客户端进行了连接!");        }    }

client端:

    public class Client {        //使用下面方式进行简单的连接:一直端口和ip进行连接        Socket client = new Socket("localhost", 8888);    }

先运行server中的main方法,然后运行client重的main方法,
在服务器端的控制台会打印:

一个客户端进行连接字样

使用DataInputStream和DataOutputStream流传输

客户端代码:

    public class Client {        public static void main(String[] args) throws UnknownHostException, IOException {        //1.创建客户端,必须制定服务器+端口          Socket client = new Socket("localhost", 8888);        //2.接收数据        /*        BufferedReader br = new BufferedReader(new InputStreamReader(client.getInputStream()));        String echo = br.readLine();//阻塞式方法   分行接收不会报错(解决方法:在server的传输字符串可以+  /r/n   或者在 write方法后面+newLine())        System.out.println(echo);        */        DataInputStream da = new DataInputStream(client.getInputStream());        String re = da.readUTF();            System.out.println(re);        }    }

服务器端:
使用while死循环使server一直在与你系那个状体,(后续会改进,使用多线程进行开发)

    public class Server{        public static void main(String[] args) throws IOException {            //1.创建 服务器制定端口            ServerSocket server = new ServerSocket(8888);            //2.接收客户端连接,阻塞式            while(true){                //死循环,一个accrpt一个客户端                Socket socket = server.accept();                System.out.println("一个客户端进行了连接!");                //3.发送数据                String msg = "欢迎使用";                //输出流    输出流和输入流是成对的            /*            BufferedWriter bw = new BufferedWriter(                    new OutputStreamWriter(                            socket.getOutputStream()));            bw.write(msg);            bw.newLine();            bw.flush();            */                DataOutputStream da = new DataOutputStream(socket.getOutputStream());                da.writeUTF(msg);                da.flush();            }        }    }

这其中的BufferedWriter 和BufferedReader 不推荐使用

运行方式,首先运行Server中的main方法,控制台会显示
启动main之后的运行状态
之后运行client的main方法
这里写图片描述

表示接收到server传过来的数据

使用InputStream和OutputStream传输

和使用DataInputStream和DataOutputStream类似,

server端:

    public class Server {    public static void main(String[] args) throws IOException {        //1.创建 服务器制定端口            ServerSocket server = new ServerSocket(8888);            //2.接收客户端连接,阻塞式            while(true){                //死循环,一个accrpt一个客户端                Socket socket = server.accept();                System.out.println("一个客户端进行了连接!");                //3.发送数据                String msg = "欢迎使用";                OutputStream os = socket.getOutputStream();                try {                    byte[] by = LoUtils.hexStr2Bytes(LoUtils.str2HexStr(msg)); //传入shuju                     String len = "0000" + by.length;                    len = len.substring(len.length() - 4);                    byte[] lenlen = len.getBytes("UTF-8");                    byte[] true_body = LoUtils.assemble(lenlen,by);                    os.write(true_body);                    os.flush();                } catch (Exception e) {                }            }        }    }

client端:

    public class Client {        public static void main(String[] args) throws UnknownHostException, IOException {            //1.创建客户端,必须制定服务器+端口              Socket client = new Socket("localhost", 8888);            //2.接收数据            byte[] lenbtyte = new byte[4];            input.read(lenbtyte, 0, 4);            int resplen = Integer.parseInt(new String(lenbtyte, "UTF-8"));            byte[] pack = new byte[resplen];            input.read(pack, 0, resplen);            String res = new String(pack, "UTF-8");            System.out.println(res);        }    }

运行成功后和上面的结果相同,就表示正确了。

工具类LoUtils:

    public class LoUtils {        //2进制到16进制Str转换        public static String str2HexStr(String str) throws Exception {            char[] chars = "0123456789ABCDEF".toCharArray();            StringBuilder sb = new StringBuilder("");            byte[] bs = str.getBytes("UTF-8");            int bit;            for (int i = 0; i < bs.length; i++) {                bit = (bs[i] & 0x0f0) >> 4;                sb.append(chars[bit]);                bit = bs[i] & 0x0f;                sb.append(chars[bit]);            }            return sb.toString();        }        /**        * 十六进制字符串转换成bytes         *          * @param src         * @return         */        public static byte[] hexStr2Bytes(String src) {            int m = 0, n = 0;            int l = src.length() / 2;            byte[] ret = new byte[l];            for (int i = 0; i < l; i++) {                m = i * 2 + 1;                n = m + 1;                ret[i] = uniteBytes(src.substring(i * 2, m), src.substring(m, n));            }            return ret;        }        //转换成 已只长度的 数组段         public static byte[] assemble(byte[]... b) throws Exception {            int length = 0;            for (byte[] bl : b) {                if (bl != null)                    length += bl.length;            }            byte[] data = new byte[length];            int count = 0;            for (int i = 0; i < b.length; i++) {                if (b[i] != null) {                    System.arraycopy(b[i], 0, data, count, b[i].length);                    count += b[i].length;                }            }            return data;        }    }

本人相对比较习惯使用DataInputStream和DataOutputStream
传输比较简单容易理解。

Tips:亲测上述方法可用特此分享