• TCP和UDP套接字编程 (java实现)


    在了解网络编程之前,我们先了解一下什么叫套接字

    套接字即指同一台主机内应用层和运输层之间的接口

    由于这个套接字是建立在网络上建立网络应用的可编程接口

    因此也将套接字称为应用程序和网络之间的应用程序编程接口!

    关于TCP和UDP这里就不作太多介绍了,我们知道TCP是面向连接的,UDP是不面向连接的,TCP可靠,UDP不可靠即可!
    我们来设计一个应用来示范一下,流程:

    1. 客户机从键盘读取一行字符串,并通过套接字发送到服务器。
    2. 服务器从连接的套接字获取这行字符串,并对其进行修改(将小写转为大写),最后再发回客户端。
    3. 客户机读取到服务器发送的修改后的字符串,并输出到屏幕。

    不说太多了,直接上代码:

    TCP套接字编程:

     客户端:

    package TCP套接字编程;
    
    import java.io.BufferedReader;
    import java.io.DataOutputStream;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.net.Socket;
    import java.net.UnknownHostException;
    
    public class TCPClient {
        public static void main(String[] args) throws UnknownHostException,
                IOException {
            // 创建两个String类型的字符串用来接收和发送字符
            String sentence;
            String modifiedSentence;
    
            // 创建输入流,用来接收键盘输入
            BufferedReader inFromUser = new BufferedReader(new InputStreamReader(
                    System.in));
    
            // 创建一个Scoket型的clientScoket用来发起服务器和客户机之间的连接
            String postname = "169.264.187.20";// 客户端ip地址(请用自己电脑的ip地址代替)
            Socket clientSocket = new Socket(postname, 6789);
    
            // 创建向服务器发送信息的输出流
            DataOutputStream outToServer = new DataOutputStream(
                    clientSocket.getOutputStream());
    
            // 创建输入流,用来接收来自服务器的字节流
            BufferedReader inFromServer = new BufferedReader(new InputStreamReader(
                    clientSocket.getInputStream()));
    
            // 读取要发送的数据
            sentence = inFromUser.readLine();
    
            // 向服务器发送数据
            outToServer.writeBytes(sentence + '
    ');
    
            // 获取从服务器接收的数据
            modifiedSentence = inFromServer.readLine();
    
            // 打印接收数据
            System.out.println("From Server:" + modifiedSentence);
    
        }
    
    }

    服务器端:

    package TCP套接字编程;
    
    import java.io.BufferedReader;
    import java.io.DataOutputStream;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.net.ServerSocket;
    import java.net.Socket;
    
    public class TCPServer {
        public static void main(String[] args) throws IOException {
            // 从客户端接收的字符串,要发送给客户端的字符串
            String clientSentence;
            String serverSentence;
    
            // 服务器打开6789端口,建立连接
            ServerSocket welcomeSocket = new ServerSocket(6789);
    
            while (true) {// 服务器的6789端口一直打开
    
                // 用此连接来获取和发送客户端数据流
                Socket connectionSocket = welcomeSocket.accept();
    
                // 获取来自客户端的数据流
                BufferedReader inFromClient = new BufferedReader(
                        new InputStreamReader(connectionSocket.getInputStream()));
    
                // 准备发送更改后的数据流
                DataOutputStream outToClient = new DataOutputStream(
                        connectionSocket.getOutputStream());
    
                // 读取收到的数据
                clientSentence = inFromClient.readLine();
    
                // 将读取到的数据都中的小写字母改为大写字母
                serverSentence = clientSentence.toUpperCase() + '
    ';
    
                // 发送修改后的数据给客户端
                outToClient.writeBytes(serverSentence);
    
            }
        }
    }

    UDP套接字编程:

    客户端:

    package UDP套接字编程;
    
    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.net.DatagramPacket;
    import java.net.DatagramSocket;
    import java.net.InetAddress;
    
    public class UDPClient {
        public static void main(String[] args) throws IOException {
            // 读取键盘输入的字节流
            BufferedReader inFromUser = new BufferedReader(new InputStreamReader(
                    System.in));
    
            // 为客户端创造一个传输信息的门,但是并没有像TCP那样建立连接
            DatagramSocket clientSocket = new DatagramSocket();
    
            // 调用DNS查询,得到主机名对应的IP地址
            InetAddress IPAddress = InetAddress.getByName(null);//null的话得到的是自己的IP地址
            System.out.println(IPAddress);
    
            // 定义需要发送的字节数组
            byte[] sendData = new byte[1024];// 不能动态开数组。。。
    
            // 定义需要接收的字节数组
            byte[] receiveData = new byte[1024];
    
            // 将从键盘接收到的数据先用字符串存起来
            String sentence = inFromUser.readLine();
    
            // 将字符串转为字节存入sendData
            sendData = sentence.getBytes();
    
            // 准备发送UDP数据报,里面包含发送内容和目的地址等信息
            DatagramPacket sendPacket = new DatagramPacket(sendData,
                    sendData.length, IPAddress, 9878);
    
            // 用这个门来发送数据报
            clientSocket.send(sendPacket);
    
            // 准备获取从服务器返回的数据报
            DatagramPacket receivePacket = new DatagramPacket(receiveData,
                    receiveData.length);
    
            // 用这个门来接收服务器发的数据报
            clientSocket.receive(receivePacket);
    
            // 将获取的数据报转换为String类型
            String modifiedSentence = new String(receivePacket.getData());
    
            // 打印从服务器收到的内容
            System.out.println("From Server:" + modifiedSentence + '
    ');
    
            // 关闭这个门
            clientSocket.close();
    
        }
    
    }

    服务器端:

    package UDP套接字编程;
    
    import java.io.IOException;
    import java.net.DatagramPacket;
    import java.net.DatagramSocket;
    import java.net.InetAddress;
    
    public class UDPServer {
        public static void main(String[] args) throws IOException {
    
            // 创建一个门,在9878端口
            DatagramSocket serverSocket = new DatagramSocket(9878);
    
            while (true) {
    
                // 定义接收数据的字节数组
                byte[] receiveData = new byte[1024];
    
                // 定义发送数据的字节数组
                byte[] sendData = new byte[1024];
    
                // 创建UDP数据报对象,准备接收UDP数据报
                DatagramPacket receivePacket = new DatagramPacket(receiveData,
                        receiveData.length);
    
                // 接收UDP数据报
                serverSocket.receive(receivePacket);
    
                // 将收到的UDP数据报转换为String字符串
                String sentence = new String(receivePacket.getData());
    
                // 得到接收到的UDP数据报的源IP地址
                InetAddress IPAddress = receivePacket.getAddress();
    
                // 得到接收到的UDP数据报的源端口号
                int port = receivePacket.getPort();
    
                // 小写字母全部变为大写字母
                String capitalized = sentence.toUpperCase();
    
                // 将字符串转换为字节数组以便发送
                sendData = capitalized.getBytes();
    
                // 准备发送字节数组,做好封装UDP数据报工作
                DatagramPacket sendPacket = new DatagramPacket(sendData,
                        sendData.length, IPAddress, port);
    
                // 通过门正式发送UDP数据报
                serverSocket.send(sendPacket);
    
            }
        }
    }

    分析:

    先运行服务器端代码,这样服务器才能工作:打开相应端口,做好接收数据的准备

    然后运行客户端代码,发送数据

    服务器工作时,对应端口一直的打开的,随时准备响应客户端的请求

    参考书籍:《计算机网络自顶向下方法》

  • 相关阅读:
    怎样查看Oracle的数据库名称sid
    request.getRemoteAddr request.getRemoteHost()
    Oracle中添加自动编号的序列
    google chrome 快捷键
    MyEclipse快捷键大全( 再排版)
    Java正则表达式应用详解
    Spring3.1 Cache注解
    Java本周总结1.
    jquery ui 自动补全
    用字符串的length实现限制文本框长度
  • 原文地址:https://www.cnblogs.com/yinbiao/p/10160574.html
Copyright © 2020-2023  润新知