网络编程---Socket

这篇具有很好参考价值的文章主要介绍了网络编程---Socket。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

网络编程基础

什么是网络编程?

在日常生活中,我们可以通过浏览器来查看文档资料、看视频、听音乐,这些都是获取网络资源的方式。而这些网络上的资源是如何显示在我们电脑上的呢?这就是网络编程。即:网络资源通过网络编程来进行数据传输。

官方一点的定义,网络编程是指网络上的主机通过不同的进程,以编程的方式实现网络通信。

当然,即使在一个主机中,只要是不同的进程基于网络来传输数据也属于网络编程。

网络编程的基本概念

发送端:数据的发送方进程,即网络通信中的源主机
接收端:数据的接收方进程,即网络通信中的目的主机
收发端:发送端和接收端两端。

请求:请求数据的发送。
响应:响应数据的发送。

客户端:获取服务的一方进程。
服务器:提供服务的一方进程。

上面提到的发送端和接收端其实是相对的:
网络编程---Socket,JavaEE初阶,网络,java

网络编程实现

Socket套接字

Socket套接字,是由系统提供用于网络通信的技术,是基于TCP/IP协议进行网络通信的基本操作单元。基于Socket套接字的网络程序开发就是网络编程。

网络通信显然是发生在传输层的过程,而传输层最出名的便是TCP协议和UDP协议了。由于TCP传输和UDP传输的特点不同。因此,Socket也被分为了俩类:TCP的Socket和UDP的Socket。下面我们分别进行介绍:
网络编程---Socket,JavaEE初阶,网络,java

UDP网络通信流程(回显服务器)

网络编程---Socket,JavaEE初阶,网络,java
网络编程---Socket,JavaEE初阶,网络,java

服务器:

  1. 创建Socket 绑定端口号
	//创建一个socket
    private DatagramSocket socket = null;

    public UdpEchoServer(int port) throws SocketException {
        socket = new DatagramSocket(port);
    }
  1. 启动服务器
	//启动服务器
    public void start() throws IOException {
        System.out.println("服务器启动");
        while (true){
            

        }
    }

因为不知道客户端什么时候发送请求,所以使用while(true) 一直保持等待

  1. 创建Packet来接收客户端传来的数据
	//接受客户端传来的数据
    DatagramPacket requestPacket = new DatagramPacket(new byte[4096],4096);
    socket.receive(requestPacket);
    String request = new String(requestPacket.getData(),0,requestPacket.getLength());

转化为字符串更方便使用。 接收数据的字节数组可以根据实际情况选择合适大小

  1. 根据请求计算响应
    //根据请求计算响应
    String response = process(request);

	//因为是回显服务器  就是返回和请求相同的数据  所以不用处理
	public String process(String request){
        return request;
    }
  1. 把响应返回给客户端
    //把响应返回给客户端
    DatagramPacket responsePacket = new DatagramPacket(response.getBytes(),0,response.getBytes().length,
                    requestPacket.getSocketAddress());
    socket.send(responsePacket);

客户端

  1. 创建Sockket 确定服务器的IP和端口号
	//用于网络编程 发送数据
    private DatagramSocket socket = null;
    //指定发送数据到哪儿
    private String serverIP;
    private int serverPort;

    public UdpEchoClient(String serverIP, int serverPort) throws SocketException {
        //先new出socket   不需要指定发送的端口   客户端会自动分配一个空闲端口
        socket = new DatagramSocket();

        //构造发送去哪儿
        this.serverIP = serverIP;
        this.serverPort = serverPort;
    }
  1. 启动客户端
	public void start() throws IOException {
        Scanner scanner = new Scanner(System.in);
        while (true){
            

        }
    }

也需要使用while(true)来时刻准备接收返回的数据

  1. 发送数据
     //1.从控制台读取要发送的数据
     System.out.println("请输入要发送的数据");
     String request = scanner.next();
     //2.构造packet
     DatagramPacket requestPacker = new DatagramPacket(request.getBytes(),request.getBytes().length,
                    InetAddress.getByName(this.serverIP),this.serverPort);
     //3.发送给服务器
     socket.send(requestPacker);
  1. 接收数据
    //1.从服务器读取响应数据
    DatagramPacket responsePacker = new DatagramPacket(new byte[4096],4096);
    socket.receive(responsePacker);
    String response = new String(responsePacker.getData(), 0,responsePacker.getLength());

    //2.把服务器响应显示在控制台
    System.out.println(response);

完整代码示例:

//服务器
public class UdpEchoServer {
    //创建一个socket
    private DatagramSocket socket = null;

    public UdpEchoServer(int port) throws SocketException {
        socket = new DatagramSocket(port);
    }

    //启动服务器
    public void start() throws IOException {
        System.out.println("服务器启动");
        while (true){
            //处理一次请求
            //1.接受客户端传来的数据
            DatagramPacket requestPacket = new DatagramPacket(new byte[4096],4096);
            socket.receive(requestPacket);
            String request = new String(requestPacket.getData(),0,requestPacket.getLength());

            //2.根据请求计算响应
            String response = process(request);

            //3.把响应返回给客户端
            DatagramPacket responsePacket = new DatagramPacket(response.getBytes(),0,response.getBytes().length,
                    requestPacket.getSocketAddress());
            socket.send(responsePacket);

            //4.打印一个日志记录当前情况
            System.out.printf("%s - %d  request: %s  response: %s \n",requestPacket.getAddress().toString(),requestPacket.getPort(),
                    request,response);

        }
    }

    public String process(String request){
        return request;
    }

    public static void main(String[] args) throws IOException {
        UdpEchoServer udpEchoServer = new UdpEchoServer(9090);
        udpEchoServer.start();
    }
}

//客户端
public class UdpEchoClient {
    //用于网络编程 发送数据
    private DatagramSocket socket = null;
    //指定发送数据到哪儿
    private String serverIP;
    private int serverPort;

    public UdpEchoClient(String serverIP, int serverPort) throws SocketException {
        //先new出socket   不需要指定发送的端口   客户端会自动分配一个空闲端口
        socket = new DatagramSocket();

        //构造发送去哪儿
        this.serverIP = serverIP;
        this.serverPort = serverPort;
    }


    public void start() throws IOException {
        Scanner scanner = new Scanner(System.in);
        while (true){
            //1.从控制台读取要发送的数据
            System.out.println("请输入要发送的数据");
            String request = scanner.next();
            //2.构造packet
            DatagramPacket requestPacker = new DatagramPacket(request.getBytes(),request.getBytes().length,
                    InetAddress.getByName(this.serverIP),this.serverPort);
            //3.发送给服务器
            socket.send(requestPacker);

            //4.从服务器读取响应数据
            DatagramPacket responsePacker = new DatagramPacket(new byte[4096],4096);
            socket.receive(responsePacker);
            String response = new String(responsePacker.getData(), 0,responsePacker.getLength());

            //5.把服务器响应显示在控制台
            System.out.println(response);

        }
    }

    public static void main(String[] args) throws IOException {
        UdpEchoClient udpEchoClient = new UdpEchoClient("127.0.0.1",9090);
        udpEchoClient.start();
    }
}

TCP网络通信流程(回显服务器)

网络编程---Socket,JavaEE初阶,网络,java
网络编程---Socket,JavaEE初阶,网络,java

服务器

  1. 创建ServerSocket用来监听
	//创建一个 监听socket 用于客户端和服务器的连接
    private ServerSocket listenSocket = null;
    public TcpEchoServer(int port) throws IOException {
        listenSocket = new ServerSocket(port);
    }
  1. 启动服务器
	//启动服务器
    public void start() throws IOException {
        System.out.println("服务器启动");
        
        while (true){
            
        }
    }
  1. 建立连接
Socket clientSocket = listenSocket.accept();
  1. 处理连接
processConnection(clientSocket);

private void processConnection(Socket clientSocket) throws IOException {
        System.out.printf("已经和客户端建立连接 ip:%s  port: %d \n",clientSocket.getInetAddress().toString(),clientSocket.getPort());

        try (InputStream inputStream = clientSocket.getInputStream();
             OutputStream outputStream = clientSocket.getOutputStream()){
            while (true){
                //1.接受请求并解析
                Scanner scanner = new Scanner(inputStream);
                if (!scanner.hasNext()){
                    //接受完毕  断开连接
                    System.out.printf("断开连接 ip: %s  port: %d",clientSocket.getInetAddress().toString(),clientSocket.getPort());

                    break;
                }
                String request = scanner.next();

                //2.根据请求计算响应
                String response = process(request);

                //3.向客户端返回响应
                PrintWriter printWriter = new PrintWriter(outputStream);
                printWriter.println(response);
                printWriter.flush();

                //处理一次请求的详情
                System.out.printf("ip: %s  port: %d  request: %s  response: %s\n",clientSocket.getInetAddress().toString(),
                        clientSocket.getPort(),request,response);
            }


        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            clientSocket.close();
        }


    }
  1. 如果有多个客户端要建立连接,使用线程池加快处理的速度
	public void start() throws IOException {
        System.out.println("服务器启动");
        ExecutorService pool = Executors.newCachedThreadPool();
        while (true){
            //1.调用listenSocket来建立连接
            Socket clientSocket = listenSocket.accept();
            //2.处理连接  如果有多个客户端发起请求  这样的响应速度就会很慢
            
            //使用线程池

            pool.submit(new Runnable() {
                @Override
                public void run() {
                    try {
                        processConnection(clientSocket);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            });
        }
    }

客户端

  1. 尝试建立连接
	//创建一个socket来传输数据
    private Socket socket = null;

    //tcp需要先建立连接再传输数据   就需要先在socket里指定出服务器
    public TcpEchoClient(String serverIP,int serverPort) throws IOException {
        socket = new Socket(serverIP,serverPort);
    }
  1. 启动服务器
	public void start() throws IOException {
        
    }

while(true)放到了传输数据的模块

  1. 发送请求并接收响应
		Scanner scanner = new Scanner(System.in);

        try (InputStream inputStream = socket.getInputStream();
             OutputStream outputStream = socket.getOutputStream()){
            while (true){
                //1.从控制台读取数据  构造请求
                System.out.println("请输入要传输的数据");
                String request = scanner.next();
                //2.发送请求给服务器
                PrintWriter printWriter = new PrintWriter(outputStream);
                printWriter.println(request);
                printWriter.flush();
                //3.从服务器读取响应
                Scanner respScanner = new Scanner(inputStream);
                String response = respScanner.next();
                //4.把响应显示在客户端
                System.out.println(response);
            }
        }

完整的代码示例:

//服务器
public class TcpEchoServer {
    //创建一个 监听socket 用于客户端和服务器的连接
    private ServerSocket listenSocket = null;
    public TcpEchoServer(int port) throws IOException {
        listenSocket = new ServerSocket(port);
    }

    //启动服务器
    public void start() throws IOException {
        System.out.println("服务器启动");
        ExecutorService pool = Executors.newCachedThreadPool();
        while (true){
            //1.调用listenSocket来建立连接
            Socket clientSocket = listenSocket.accept();
            //2.处理连接  如果有多个客户端发起请求  这样的响应速度就会很慢
           
            //使用线程池

            pool.submit(new Runnable() {
                @Override
                public void run() {
                    try {
                        processConnection(clientSocket);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            });
        }
    }

    private void processConnection(Socket clientSocket) throws IOException {
        System.out.printf("已经和客户端建立连接 ip:%s  port: %d \n",clientSocket.getInetAddress().toString(),clientSocket.getPort());

        try (InputStream inputStream = clientSocket.getInputStream();
             OutputStream outputStream = clientSocket.getOutputStream()){
            while (true){
                //1.接受请求并解析
                Scanner scanner = new Scanner(inputStream);
                if (!scanner.hasNext()){
                    //接受完毕  断开连接
                    System.out.printf("断开连接 ip: %s  port: %d",clientSocket.getInetAddress().toString(),clientSocket.getPort());

                    break;
                }
                String request = scanner.next();

                //2.根据请求计算响应
                String response = process(request);

                //3.向客户端返回响应
                PrintWriter printWriter = new PrintWriter(outputStream);
                printWriter.println(response);
                printWriter.flush();

                //处理一次请求的详情
                System.out.printf("ip: %s  port: %d  request: %s  response: %s\n",clientSocket.getInetAddress().toString(),
                        clientSocket.getPort(),request,response);
            }


        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            clientSocket.close();
        }


    }

    //处理响应
    public String process(String request){
        return request;
    }

    public static void main(String[] args) throws IOException {
        TcpEchoServer tcpEchoServer = new TcpEchoServer(9090);
        tcpEchoServer.start();
    }
}
//客户端
public class TcpEchoClient {
    //创建一个socket来传输数据
    private Socket socket = null;

    //tcp需要先建立连接再传输数据   就需要先在socket里指定出服务器
    public TcpEchoClient(String serverIP,int serverPort) throws IOException {
        socket = new Socket(serverIP,serverPort);
    }

    public void start() throws IOException {
        Scanner scanner = new Scanner(System.in);

        try (InputStream inputStream = socket.getInputStream();
             OutputStream outputStream = socket.getOutputStream()){
            while (true){
                //1.从控制台读取数据  构造请求
                System.out.println("请输入要传输的数据");
                String request = scanner.next();
                //2.发送请求给服务器
                PrintWriter printWriter = new PrintWriter(outputStream);
                printWriter.println(request);
                printWriter.flush();
                //3.从服务器读取响应
                Scanner respScanner = new Scanner(inputStream);
                String response = respScanner.next();
                //4.把响应显示在客户端
                System.out.println(response);
            }
        }
    }

    public static void main(String[] args) throws IOException {
        TcpEchoClient tcpEchoClient = new TcpEchoClient("127.0.0.1",9090);
        tcpEchoClient.start();
    }

}

两种实现方式的区别

为什么实现TCP的Socket时要使用多线程而在UDP的Socket不用呢?

  1. UDP是无连接的,服务器不关心是哪个客户端发送过来的请求都会进行处理。
  2. TCP是有连接的,每次建立连接后服务器都得处理对应客户端的多次请求,此时无法接受其他客户端的连接,不满足实际需求。所以得使用多线程来同时处理多个客户端的请求。

为什么TCP的Socket要关闭,ServerSocket和UDP的Socket不用关闭?文章来源地址https://www.toymoban.com/news/detail-738600.html

  1. Socket也是一个文件,一个进程能同时打开文件的个数是有限的。因为文件描述符表是有限的。
  2. UDP的Socket不需要建立连接,它在UDP服务器中只有唯一一个对象,不会把文件描述符表占满,随着进程退出会自动释放。
  3. ServerSocket,它在TCP服务器中只有唯一一个对象,不会把文件描述符表占满,随着进程退出会自动释放。
  4. Socket,在TCP的服务器中,每次和一个新的客户端建立连接都要创建一个新的。有可能把文件描述符表占满,就需要释放。

到了这里,关于网络编程---Socket的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Java 网络编程 —— Socket 详解

    在【客户端/服务端】的通信模式中,客户端需要主动构造与服务器连接的 Socket,构造方法有以下几种重载形式: 除了第一个不带参数的构造方法,其他构造方法都会试图建立与服务器的连接,一旦连接成功,就返回 Socket 对象,否则抛出异常 1. 设定等待建立连接的超时时间

    2024年02月01日
    浏览(27)
  • Java网络Socket编程-websocket

    实现一个用于监测 WebSocket 连接状态的线程类,其作用是通过创建一个 WebSocket 客户端,连接到指定的 WebSocket 地址,并监测连接的状态。 代码中的 WebSocketThread 类继承自 Thread ,意味着它可以在单独的线程中执行。该线程类使用 Tyrus 提供的 @ClientEndpoint 注解来标识这是一个

    2024年02月08日
    浏览(34)
  • Java网络编程-Socket实现数据通信

    本文主要是为下一篇Websockt做铺垫,大家了解socket的一些实现。 网络编程是指利用计算机网络进行程序设计、开发的技术。网络编程主要包含三个要素,分别是: IP地址和端口号 传输协议 Socket 在计算机网络中,每台计算机都有一个IP地址,用于唯一标识该计算机在网络中的

    2024年02月10日
    浏览(31)
  • Java中的网络编程------基于Socket的TCP编程和基于UDP的网络编程,netstat指令

    Socket 在Java中,Socket是一种用于网络通信的编程接口, 它允许不同计算机之间的程序进行数据交换和通信 。Socket使得网络应用程序能够通过TCP或UDP协议在不同主机之间建立连接、发送数据和接收数据。以下是Socket的基本介绍: Socket类型 :在Java中,有两种主要类型的Socket,分

    2024年02月10日
    浏览(30)
  • Java网络编程基础:TCP Socket套接字编程 IntAddress UDP等...

    目录 一,网络基础 1.IP地址 2.端口 3.TCP/UDP协议 4.网络编程开发模式  二,基于套接字的Java网络编程 1.Socket  2.InetAddress 三.基于TCP的Socket网络编程 1.单服务器端与单Socket客户端一次通讯 2.单服务器端接收多次通讯  3.TCP网络通讯补充 四,基于UDP的网络编程 1. DatagramSocket:收发

    2024年04月29日
    浏览(30)
  • 【Java EE初阶十五】网络编程TCP/IP协议(二)

            tcp的socket api和U大片的socket api差异很大,但是和前面所讲的文件操作很密切的联系         下面主要讲解两个关键的类:         1、ServerSocket:给服务器使用的类,使用这个类来绑定端口号         2、Socket:即会给服务器使用,又会给客户端使用;         

    2024年02月20日
    浏览(40)
  • 计算机网络技术与JAVA网络编程手写Socket聊天室-----JAVA入门基础教程-----计算机网络经典

    import java.io.*; import java.net.Socket; import java.util.Scanner; public class ChatClient { public static void main(String[] args) { try { Socket socket = new Socket(\\\"127.0.0.1\\\",9090); new Thread(new Runnable() { @Override public void run() { InputStream inputStream = null; while(true) { try { inputStream = socket.getInputStream(); } catch (IOException e)

    2024年02月15日
    浏览(44)
  • 【Java】网络编程与Socket套接字、UDP编程和TCP编程实现客户端和服务端通信

    为什么需要网络编程? 现在网络普及程序越来越高,网络上保存着我们日常生活中需要的各种资源,使用程序通过网络来获取这些资源的过程就需要网络编程来实现。 什么是网络编程? 网络编程,指网络上的主机,通过不同的进程以程序的方式实现网络通信(网络数据传输)

    2024年02月17日
    浏览(51)
  • 【Java网络编程】基于UDP-Socket 实现客户端、服务器通信

    ​ 哈喽,大家好~我是你们的老朋友: 保护小周ღ   本期为大家带来的是网络编程的 UDP Socket 套接字,基于 UDP协议的 Socket 实现客户端服务器通信 ,Socket 套接字可以理解为是,传输层给应用层提供的一组 API,如此程序,确定不来看看嘛~~ 本期收录于博主的专栏 : JavaEE_保

    2024年02月02日
    浏览(46)
  • Java网络编程(二)Socket 套接字(TCP和UDP),以及TCP的回显

    我们软件工作者,着重编写的是应用层的代码,但是发送这个数据,我们就需要将应用层传输到传输层,也就意味着我们需要调用应用层的API,统称为 Socket API。 套接字的分类: 流套接字:使用传输层TCP协议 特点: 有连接:使用 TCP 通信的双方,需要时刻保存对方的相关消

    2024年02月09日
    浏览(42)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包