唐僧喜欢小龙女

导航

SOCKET编程学习

1、基础知识整理

/**
 * 一、网络编程中的两个问题
 *   1、如何准确的定位网络上一台或多台主机并且定位主机上的应用
 *   2、找到主机后如何可靠高效的进行数据传输
 * 二、解决办法
 *   1、对应问题一:IP和端口
 *   2、对应问题二:提供网络通信协议 TCP/IP模型(应用层、传输层、网络层、物理层)
 *      数据传输按照这样规定的规则协议来传输,并且每一层有具体的协议例如应用层(http、FTP)
 *      传输层(TCP、UDP)、网层层(IP)
 *
 * 三、IP 和端口具体了解
 *   Java中InetAddress这个类代表一个IP
 *   DNS 域名服务解析器 用来解析域名的
 *   IP+端口 组合起来叫 网络套接字 socket,可以理解成网络中的一个节点
 * 四、网络通信协议具体了解
 *   1、分为四层 应用层 传输层 网络层 物理层 每一层解决不同的问题,同层之间可以通信,层与层之间进行彼此通信,不能隔层通信
 *   2、传输层有两个重要的协议 TCP(传输控制协议)、UDP(用户数据报协议)传输层和网络层 组合在一起叫TCP/IP协议簇
 *   3、TCP的建立链接和断开链接需要三次握手和4次挥手数据安全可靠、UDP不用,只管发消息类似与发垃圾短息,数据不安全会丢数据
 *      UDP可以用在视频传播这里,即使丢一点数据也不影响观看
 * 五、TCP编程或者UDP编程
 *    TCP编程或者UDP编程也叫socket编程
 *
 *
 *
 */

2、InetAddress常见的API

public class IntenetAddressTest {
    public static void main(String[] args) {
        try{
            InetAddress inetAddress =  InetAddress.getByName("192.168.1.19");
            System.out.println(inetAddress);

            InetAddress inet =  InetAddress.getByName("www.baidu.com");
            System.out.println(inet);

            InetAddress local = InetAddress.getLocalHost();
            System.out.println(local);

            InetAddress loop = InetAddress.getLoopbackAddress();
            System.out.println(loop);

            //获取域名
            System.out.println(loop.getHostName());
            //获取域名对应的ip
            System.out.println(loop.getHostAddress());
            
        }catch (Exception e){

        }

    }
}

3、TCP编程

3.1 服务端代码

@RestController
public class ProviderController {

    @RequestMapping("/provider")
    public void provider(){
        ServerSocket serverSocket = null;
        Socket socket = null;
        InputStream inputStream = null;
        ByteArrayOutputStream byteArrayOutputStream = null;
        try{

            byteArrayOutputStream = new ByteArrayOutputStream();
            byte[] bytes = new byte[5];
            int len;
            //这里不用指定ip,程序跑在哪里就用当前服务器的ip,源码里面有获取ip的方法
            serverSocket = new ServerSocket(8015);
            //一直监听着端口,这个端口不能和server.port重复
            while (true){
                socket = serverSocket.accept();
                inputStream = socket.getInputStream();
                while ((len = inputStream.read(bytes))!= -1){
                    byteArrayOutputStream.write(bytes,0,len);
                }

                System.out.println(byteArrayOutputStream.toString());
                //
                byteArrayOutputStream.reset();
                System.out.println("收到了来自于"+socket.getInetAddress().getHostAddress()+"的数据");
            }

        }catch (Exception e){

        }finally {
            try{
                if(byteArrayOutputStream != null){
                    byteArrayOutputStream.close();

                }if(inputStream != null){
                    inputStream.close();

                }if(socket !=null){
                    socket.close();

                }if(serverSocket !=null){
                    serverSocket.close();
                }
            }catch (Exception e){

            }

        }

    }

}

3.2 客户端代码

@RestController
public class ConsumerController {
//
    @RequestMapping("/consumer")
    public void consumer(){
        OutputStream outputStream = null;
        Socket socket = null;

        try{
            //对方的ip
            InetAddress inetAddress = InetAddress.getByName("127.0.0.1");
            //这个端口不能和server.port重复
            socket = new Socket(inetAddress,8015);
            outputStream = socket.getOutputStream();
            outputStream.write("你好 我是客户端 mm".getBytes());
            outputStream.close();
            socket.close();
        }catch (Exception e){

        }finally {
            try{
                if(outputStream != null){
                    outputStream.close();
                }if(socket != null){
                    socket.close();
                }
            }catch (Exception e){

            }
        }
    }
}

3.3 测试结果  

4、UDP编程

4.1 服务端

/**
 *
 *  UDP测试服务端
 *
 */
@RestController
public class UDPServerController {

    private final int MAX_SIZE = 1024;
    private final int PORT = 8080;

    private DatagramSocket socket;


    @RequestMapping("/reveiceUdp")
    public void receiveUdpdata() throws Exception{

        try {
            //这里不用指定IP但是端口一定要指定
            socket = new DatagramSocket(PORT);
            System.out.println("UDP server start.");
            int count = 0;
            while(true) {
                byte[] buffer = new byte[MAX_SIZE];
                DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
                socket.receive(packet);
                String data = new String(packet.getData(),0,packet.getLength());
                System.out.println("server receive data : "+data);
                //服务端响应给客户端的消息
                byte[] send = String.format("yes,udp server. %d times", count++).getBytes();
                packet.setData(send);
                socket.send(packet);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            socket.close();
        }
        
    }
}

4.2 客户端

/**
 *
 *  UDP测试
 *
 *
 */
@RestController
public class UDPConsumerController {

    @RequestMapping("/sendUdpData")
    public void udpTest()throws Exception{


        String str = "我是 udp 方式发送的导弹";
        byte[] data = str.getBytes();
        //创建一个socket
        DatagramSocket socket = null;
        try {
            // 这里用用带参的构造器,不用带参的发不出去消息
            socket =  new DatagramSocket(10000);

            int port = 8080;
            //地址
            InetAddress inetAddress = InetAddress.getLocalHost();
            /**
             * 创建数据包用下面的构造器
             * 1、报文
             * 2、从哪里开始发
             * 3、发多长
             * 4、服务端的地址
             * 5、端口号
             */

            DatagramPacket packet = new DatagramPacket(data, data.length, inetAddress, port);
            //显示的调用API 来发送信息,这个和TCP编程还不一样哈。
            socket.send(packet);


            //接收服务端给的响应日志
            byte[] buffer = new byte[1024];
            DatagramPacket receiver = new DatagramPacket(buffer, buffer.length);
            socket.receive(receiver);
            String res = new String(receiver.getData(),0,receiver.getLength());
            System.out.println("response by server : "+res);
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            socket.close();
        }
    }
}

4.3 测试结果

先启动服务端然后启动客户端发消息

 

 

 

posted on 2021-08-08 17:59  与时具进&不忘初心  阅读(97)  评论(0编辑  收藏  举报