网络通信基础

2023-02-19  本文已影响0人  内卷程序员

Boss的需求

规划

第一步 网络基础知识

万丈高楼从地起,很多虽然很简单的东西,我也要再次走一遍,不漏掉任何一部分。

网络分层模型
image.png image.png image.png
数据传输方式
IP地址
image.png
端口和端口号
  • 固定端口号是指众所周知的端口号,范围从0到1023,这些端口号一般固定分配给一些服务,比如21端口分配给FTP服务,25端口分配给SMTP(服务,80端口分配给HTTP服务。
  • 动态端口号是开发序员开发应用程序使用端口号称为动态端口号, 范围是从1024到65535
TCP协议
UDP协议
  • 无连接:知道对端的IP和端口号就直接进行传输,不需要建立连接;
  • 不可靠传输:没有任何安全机制,发送端发送数据报以后,如果因为网络故障该段无法发到对方,UDP协议层也不会给应用层返回任何错误信息;
  • 面向数据报:应用层交给UDP多长的报文,UDP原样发送,既不会拆分,也不会合并;
  • 全双工:UDP允许通信双方的应用进程在任何时候都能发送数据,UDP的socket既能读,也能写
Socket
image.png
image.png
image.png image.png
TCP 网络应用程序
image.png
//Socket服务端

public class Socket_Serverextends Thread {

    private ServerSocketserverSocket;

    public Socket_Server(int port) throws IOException {  //创建非绑定服务器套接字套接字

       serverSocket = new ServerSocket(port);          //服务器应用程序对象,侦听客户端请求

       serverSocket.setSoTimeout(10000);               //设置连接超时时间
   }

    public void run() {

        while (true) {

            try {

           System.out.println("等待远程连接,端口为:" + serverSocket.getLocalPort());//获取本地端口

           Socket server = serverSocket.accept();//通过accept()获取一个Socket对象

           System.out.println("远程主机地址为:" + server.getRemoteSocketAddress());//获取远程主机地址

           DataInputStream in = new DataInputStream(server.getInputStream());//声明数据输入流对象,读入数据

           System.out.println(in.read());

                   DataOutputStream out = new DataOutputStream(server.getOutputStream());//声明数据输出流对象,写出数据

                   out.writeUTF("主机号为:" + server.getRemoteSocketAddress() + "连接成功");
  
            } catch (SocketTimeoutException s) {

                System.out.println("Socket time out");

                break;

            } catch (IOException i) {

                i.printStackTrace();

                break;

            }

        }

    }

    public static void main(String args[]) {

        int port = Integer.parseInt(args[0]);

        try {

            Thread t = new Socket_Server(port);

            t.run();

        } catch (IOException i) {

            i.printStackTrace();

        }
    }
}
 

TCP客户端


public class Socket_Client {

    public static void main(String args[]) {

        String serverName = args[0];

        int port = Integer.parseInt(args[1]);

        try {

            System.out.println("连接到主机:" + serverName + ",端口号:" + port);

            Socket client = new Socket(serverName, port);                    //创建套接字

           System.out.println("远程主机地址:" + client.getRemoteSocketAddress());

            OutputStream outToServer = client.getOutputStream();     //输出流写出数据(返回此套接字的输出流)

            DataOutputStream out = new DataOutputStream(outToServer);//声明数据输出流对象,写出数据

// 按照UTF-8写入(UTF8变长,开头2字节是由writeUTF函数写入的长度信息,方便readUTF函数读取)

           out.writeUTF("Hello from" + client.getRemoteSocketAddress());

            InputStream inFromServer = client.getInputStream();//输入流读入数据(返回此套接字的输入流)

           DataInputStream in = new DataInputStream(inFromServer);//声明数据输入流对象,读入数据

           System.out.println("服务器响应:" + in.readUTF());//读取由writeUTF函数写入的信息

           client.close();

        } catch (IOException i) {

            i.printStackTrace();

        }

    }

UDP应用程序
image.png

public class ToUpperUDPServer {  
      
    //服务器IP  
    public static final String SERVER_IP = "127.0.0.1";  
      
    //服务器端口号  
    public static final int SERVER_PORT = 10005;  
      
    //最多处理1024个字符  
    public static final int MAX_BYTES = 1024;  
      
    //UDP使用DatagramSocket发送数据包  
    private DatagramSocket serverSocket;  
      
    /*** 
     * 启动服务器 
     * @param 服务器监听的端口号,服务器ip无需指定,系统自动分配 
     */  
    public void startServer(String serverIp, int serverPort) {  
        try {  
            //创建DatagramSocket  
            InetAddress serverAddr = InetAddress.getByName(serverIp);  
            serverSocket = new DatagramSocket(serverPort, serverAddr);  
              
            //创建接收数据的对象  
            byte[] recvBuf = new byte[MAX_BYTES];  
            DatagramPacket recvPacket = new DatagramPacket(recvBuf , recvBuf.length);  
              
            //死循环,一直运行服务器  
            while (true) {  
                //接收数据,会在这里阻塞,直到有数据到来  
                try {  
                    serverSocket.receive(recvPacket);  
                } catch (IOException e) {  
                    e.printStackTrace();  
                }  
                  
                  
                String recvStr = new String(recvPacket.getData(), 0, recvPacket.getLength());  
                  
                //拿到対端的ip和端口  
                InetAddress clientAddr = recvPacket.getAddress();  
                int clientPort = recvPacket.getPort();  
                  
                //回传数据  
                String upperString = recvStr.toUpperCase();  
                byte[] sendBuf = upperString.getBytes();  
                DatagramPacket sendPacket = new DatagramPacket(sendBuf, sendBuf.length, clientAddr, clientPort);  
                try {  
                    serverSocket.send(sendPacket);  
                } catch (IOException e) {  
                    e.printStackTrace();  
                }  
            }  
              
        } catch (SocketException e) {  
            e.printStackTrace();  
        } catch (UnknownHostException e2) {  
            e2.printStackTrace();  
        } finally {  
            //记得关闭Socket  
            if (null != serverSocket) {  
                serverSocket.close();  
                serverSocket = null;  
            }  
        }  
    }  
      
    public static void main(String[] args) {  
        ToUpperUDPServer server = new ToUpperUDPServer();  
        server.startServer(SERVER_IP, SERVER_PORT);  
    }  
}  
public class ToUpperUDPClient {  
      
    private DatagramSocket clientSocket;  
      
    public String toUpperRemote(String serverIp, int serverPort, String str) {  
        String recvStr = "";  
          
        try {  
            //创建UDP Socket  
            clientSocket = new DatagramSocket();  
              
            //向服务器发送数据  
            byte[] sendBuf;  
            sendBuf = str.getBytes();  
            InetAddress serverAddr = InetAddress.getByName(serverIp);  
            DatagramPacket sendPacket   
                = new DatagramPacket(sendBuf ,sendBuf.length , serverAddr , serverPort);  
            try {  
                clientSocket.send(sendPacket);  
            } catch (IOException e) {  
                e.printStackTrace();  
            }  
              
            //接收服务器的响应  
            byte[] recvBuf = new byte[ToUpperUDPServer.MAX_BYTES];  
            DatagramPacket recvPacket  
                = new DatagramPacket(recvBuf , recvBuf.length);  
            try {  
                clientSocket.receive(recvPacket);  
            } catch (IOException e) {  
                e.printStackTrace();  
            }  
              
            //显示响应  
            recvStr = new String(recvPacket.getData() , 0 ,recvPacket.getLength());  
        } catch (SocketException e1) {  
            e1.printStackTrace();  
        } catch (UnknownHostException e2) {  
            e2.printStackTrace();  
        } finally {  
            if (null != clientSocket) {  
                clientSocket.close();  
                clientSocket = null;  
            }  
        }  
          
        return recvStr;  
    }  
      
    public static void main(String[] args) {  
        ToUpperUDPClient client = new ToUpperUDPClient();  
        String recvStr = client.toUpperRemote(ToUpperUDPServer.SERVER_IP, ToUpperUDPServer.SERVER_PORT, "aaaAAAbbbBBBcccCCC");  
        System.out.println("收到:" + recvStr);  
    }  
} 
上一篇 下一篇

猜你喜欢

热点阅读