java中Socket编程

来源:互联网 发布:java 方法是什么 编辑:程序博客网 时间:2024/06/12 14:36

TCP

  1. 面向连接 和打电话一样,必须要建立通信。
  2. 可靠性 不会丢失文件。
  3. 顺序,无差错。

Socket

套接字
网络上的两个程序通过一个双向的通讯连接实现数据的交换,这个双向链路的一端称为一个

Socket

一个Socket由一个IP地址和一个端口号唯一确定。
cmd netstat -ano

IP

确定唯一的一台电脑地址

端口

确定电脑上唯一的应用程序
0~1023被系统保留。
1024-65535 每个端口只允许一个程序访问。

代码步骤

1. 服务端 创建ServerSocketServerSocket只用来等待客户端连接,不能通过他进行交互。2. 等待客户端链接Socket socket = ServerSocket.accept();等待客户端连接,返回一个Socket实例3. 客户端通过Sockek进行连接Socket socket = new Socket(host,port);4. 通过两边的socket获取流进行输入输出。注意1. 程序开过一次后,会占用端口,注意关闭程序,否则不能运行第二次。2. 每个阻塞式方法都必须存在一条新线程中,否则阻塞后其他方法无法执行,如等待客户端连接 accept() , 键盘输入 input.next() ,读数据while((len=is.read(buf))!=-1) 等操作都会阻塞。3. 启动新线程一般放在最上面,不能放在阻塞式方法的后面,否则执行不了,或者出现问题
//服务端public class Server2 extends Thread {    // 能同时连接多台电脑    ServerSocket server;    List<Socket> list = new ArrayList<>();    public Server2() {        try {            server = new ServerSocket(8888);        } catch (IOException e) {            e.printStackTrace();        }    }    @Override    public void run() {        super.run();        while (true) {            try {                // 每次循环到这里 都会再次等待客户端连接                Socket socket = server.accept();                // 添加所有链接的用户                System.out.println(socket.getInetAddress().getHostAddress()                        + "连上了");                sendMessageToAllPC(socket.getInetAddress().getHostAddress()                        + "上线了");                list.add(socket);                new ReaderThread(socket).start();                // 开个线程            } catch (IOException e) {            }        }    }    // 写的方法    public void sendMessageToAllPC(String msg) {        for (Socket socket : list) {            if (socket != null && socket.isConnected()) {                OutputStream os;                try {                    os = socket.getOutputStream();                    os.write(msg.getBytes());                    os.flush();                    // 千万不要关                } catch (IOException e) {                }            }        }    }    // 专用读的线程    class ReaderThread extends Thread {        InputStream is;        public ReaderThread(Socket socket) {            try {                is = socket.getInputStream();            } catch (IOException e) {            }        }        // 只做读操作        @Override        public void run() {            // 读了你的消息,转发给其他所有用户            byte[] buf = new byte[1024];            int len = 0;            try {                while ((len = is.read(buf)) != -1) {                    sendMessageToAllPC(new String(buf, 0, len));                }            } catch (IOException e) {            }        }    }}//客户端public class Client2 extends Thread {    Socket socket;    String name;    public Client2(String name) {        this.name = name;        try {            socket = new Socket("192.168.18.250", 8888);        } catch (UnknownHostException e) {            e.printStackTrace();        } catch (IOException e) {            e.printStackTrace();        }    }    @Override    public void run() {        // 读线程        new ReaderThread().start();        // 写操作        try {            Scanner input = new Scanner(System.in);            String speak = null;            // 写的流            OutputStream os = socket.getOutputStream();            do {                speak = input.next();                os.write((name + ":" + speak).getBytes());                os.flush();            } while (!speak.equals("bye"));            input.close();            socket.close();        } catch (IOException e) {            e.printStackTrace();        }    }    class ReaderThread extends Thread {        @Override        public void run() {            try {                InputStream is = socket.getInputStream();                int len = 0;                byte[] buf = new byte[1024];                while ((len = is.read(buf)) != -1) {                    System.out.println(new String(buf, 0, len));                }            } catch (IOException e) {                e.printStackTrace();            }        }    }}

UDP

  1. 面向无连接,没有服务端与客户端,和发短信一样,分为发送方和接收方。
  2. UDP有大小限制,每个数据报只有64KB大小,报文。
  3. 不可靠协议,数据不一定会到达,也不一定是按顺序到达。

广播

广播地址是192.168.*.255
发送步骤

 // 1.建立发送的主机地址SocketAddress address = new InetSocketAddress(host, port);// 2.建立数据报// 长度一定要注意 转字节获取长度 DatagramPacket dp = new DatagramPacket(msg.getBytes(),msg.getBytes().length, address); // 2. 发送数据报 socket.send(dp);
public class UDPUtils extends Thread {    // 收发数据    // 端口号    DatagramSocket socket;    public UDPUtils(int port) {        // 我在本机器上,监听该端口        try {            socket = new DatagramSocket(port);        } catch (SocketException e) {            e.printStackTrace();        }    }    // 发送数据报    // 1. 对方端口    // 2. 对方ip地址    // 3. 数据    public void sendMessage(String host, int port, String msg)            throws IOException {        // 1.建立发送的主机地址        SocketAddress address = new InetSocketAddress(host, port);        // 2.建立数据报        // 长度一定要注意 转字节获取长度        DatagramPacket dp = new DatagramPacket(msg.getBytes(),                msg.getBytes().length, address);        // 2. 发送数据报        socket.send(dp);    }    // 收报    @Override    public void run() {        // 一个包 如果缓冲区不够,就丢失了        byte[] buf = new byte[65535];        DatagramPacket packet = new DatagramPacket(buf, buf.length);        while (true) {            try {                // 阻塞式                socket.receive(packet);                // 收到了数据报                // 拆包                String msg = new String(packet.getData(), 0, packet.getLength());                System.out.println(msg);            } catch (IOException e) {                e.printStackTrace();            }        }    }}//mian方法类public class Test {    /**     * TCP 协议 Socket 用来连接 ServerSocket 服务端 用来监听客户端连接 accept() 阻塞并等待客户端的链接     *      * 通过Socket的getInputStream和getOutputStream来获取流进行通信     *      *      * Tcp特点 保持连接状态 不会丢失数据 并且数据顺序到达     *      *      * @param args     */    public static void main(String[] args) {        UDPUtils utils = new UDPUtils(7777);        utils.start();        Scanner input = new Scanner(System.in);        int index = 0;        while (index++ < 5) {            String msg = input.next();            // 发送给谁            try {                utils.sendMessage("192.168.18.255", 7777, msg);            } catch (IOException e) {                e.printStackTrace();            }        }        input.close();    }}
0 0
原创粉丝点击