网络编程之Socket

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

在之前的文章《网络编程杂谈之TCP协议》中,我们阐述了TCP协议的基本概念,TCP作为一种可靠的、面向连接的数据传输协议,确保了数据在发送和接收之间的可靠性、顺序性和完整性,特点可以概括如下:

1、面向连接:在进行数据传输之前,TCP需要客户端和服务器之间建立一个连接,这个连接包括一系列的握手和协商步骤,以确保通信双方都准备好进行数据传输。

2、可靠性:TCP是一种可靠的协议,它使用各种机制来确保数据的可靠传输,包括数据分段的确认和重传机制,以及流量控制等多种手段。

3、顺序性:TCP保证数据段的到达顺序与发送顺序相同,即使数据在传输过程中被拆分成多个数据包,接收方也会将它们按照正确的顺序重新组装,比如说链接的一方发了ABC,那么接收的一方收到的也一定是ABC。

4、流量控制:TCP使用滑动窗口协议来实现流量控制,确保了发送方不会以超过接收方处理能力的速度发送数据,从而避免了数据丢失和网络拥塞。

5、拥塞控制:TCP还具有拥塞控制机制,它可以检测到网络中的拥塞并采取相应的措施来减轻拥塞,从而实现降低发送速率和重新发送丢失的数据包。

6、面向字节流:TCP是面向字节流的协议,它不会保留消息边界。这意味着接收方需要自行解析和分割接收到的字节流,以还原原始消息。

7、可靠的错误检测和纠正:TCP具有强大的错误检测和纠正机制,它可以检测并纠正在数据传输过程中出现的错误,以确保数据的完整性。

8、全双工通信:TCP支持全双工通信,所谓全双工是指建立连接后,通信双方可以同时发送和接收数据,而不需要等待对方的响应。

9、Socket(套接字):TCP使用端口号来标识不同的应用程序或服务,通信的两端通过IP地址和端口号来建立连接,而套接字(Socket)就是对其中任意一端的抽象,分为服务器端套接字(Server Socket)或客户端套接字(Client Socket),分别用于服务器和客户端的通信。

总的来说,TCP协议作用于传输层且适用于大多数需要可靠数据传输的应用程序,如文件传输、上位机通信等,并可以做为其他应用层协议的实现基础,如HTTP、MQTT等。

在代码实现层面,Socket是指一种编程接口(API),不同开发语言基本上都围绕Socket提供了一组用于创建、连接、发送和接收数据的API。下面我们以Java为例,通过java.net包下提供的Socket操作API与 java.io包下提供的IO操作API, 实现一个基本的TCP服务端与客户端的监听、链接并进行消息收发的示例。

服务端

在TCP服务端的实现中我们需要先定义一个ServerSocket对象,并实现对指定IP与端口号的绑定与监听,这里需要注意的是如果一直没有客户端链接,serverSocket.accept会一直处在阻塞状态,一旦有客户端链接事件发生才会向下执行,而服务需要满足与多个客户端进行链接,这也是为什么我们需要一个while (true)去一直轮询执行,因为我们其实是不知道客户端什么时候会链接上来的,下面的读写操作也是同一个道理, 所以为了不影响主线程accept新的客户端,我们把完成链接的Socket开启一个独立的线程或者抛给线程池来处理后续IO读写操作,这是一种典型的BIO(Blocking I/O)即阻塞IO的处理模式。

public class BioServer {  
      
    public static void main(String[] args) throws IOException{  
         
       ExecutorService executor = new ThreadPoolExecutor(2, 4, 1000, TimeUnit.SECONDS, new ArrayBlockingQueue<>(10),  
             new ThreadPoolExecutor.CallerRunsPolicy());  
       ServerSocket serverSocket = new ServerSocket();  
       serverSocket.bind(new InetSocketAddress("127.0.0.1",9091));//绑定IP地址与端口,定义一个服务端socket,开启监听  
       while (true) {  
          Socket socket = serverSocket.accept();//这里如果没有客户端链接,会一直阻塞等待,一旦有客户端链接就会向下执行
          executor.execute(new BioServerHandler(socket)); //我们把链接Socket抛给线程池
            
       }  
    }  
}

读写操作是通过Socket获取InputStream与OutputStream来完成的,这里的Input与Output是站在你程序的视角来区分的,所以Input是收,Output是发,同理inputStream.read作为IO读操作也是阻塞的,程序只有接受到数据时才会向下执行,由于我们不确定Socket链接的读写操作何时发生,也只能依靠 while (true)轮询执行。

public class BioServerHandler implements Runnable{

    private final Socket socket;
    
    public BioServerHandler(Socket socket) {
       this.socket=socket;
    }
    
    @Override
    public void run() {
       // TODO Auto-generated method stub
       try {
          
          while (true) {
             byte[] rbytes = new byte[1024];
             InputStream inputStream =  socket.getInputStream(); //通过IO输入流接受消息
             int rlength=inputStream.read(rbytes, 0, 1024); //读操作阻塞,一旦接受到数据向下执行并返回接收到的数据长度
             byte[] bytes = new byte[rlength];
             System.arraycopy(rbytes, 0, bytes, 0, rlength);
             String message = new String(bytes);
             System.out.printf("Client: %s%n", message);

             PrintStream writer = new PrintStream(socket.getOutputStream()); //通过IO输出流发送消息
             writer.println("Hello BIO Client");
          }

          
       } catch (IOException e) {
          // TODO Auto-generated catch block
          e.printStackTrace();
       }
       
    }

}

客户端

public class BioClient {  
    public static void main(String[] args) throws IOException, InterruptedException {  
        Socket socket = new Socket();  
        socket.connect(new InetSocketAddress("127.0.0.1", 9091));  
  
        while (true) {  
            if (!socket.isConnected()) {  
                System.out.print("connecting...");  
                continue;  
            }  
  
            PrintStream writer = new PrintStream(socket.getOutputStream());  
            writer.write("Hello BIO Server".getBytes(StandardCharsets.UTF_8));  
  
            BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));  
            String message = reader.readLine();  
            System.out.printf("Server: %s%n", message);  
        }  
  
  
    }  
}

通过上面代码大家能够对Java下TCP网络编程的开发、Socket的操作、BIO(阻塞IO)模型有了基本的了解,当然一个完整的TCP服务或客户端开发需要考虑的问题还有很多,如IO与线程模型、协议的制定、链接的管理、应用层报文粘包、半包等等,后续我们会在此基础上进行进一步的扩展与完善。







关注微信公众号,查看更多技术文章。

网络编程之Socket文章来源地址https://www.toymoban.com/news/detail-711927.html

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

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

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

相关文章

  • 网络编程之Socket

    在之前的文章《网络编程杂谈之TCP协议》中,我们阐述了TCP协议的基本概念,TCP作为一种可靠的、面向连接的数据传输协议,确保了数据在发送和接收之间的可靠性、顺序性和完整性,特点可以概括如下: 1、面向连接:在进行数据传输之前,TCP需要客户端和服务器之间建立

    2024年02月08日
    浏览(38)
  • 网络编程---Socket

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

    2024年02月06日
    浏览(45)
  • 【计算机网络】4 Socket网络编程

    目录 写在前面的话 概览 环境 URL请求程序: 2. 系统时间查询 服务端 T_TCPServer.py代码 客户端 T_TCPClient.py代码 运行效果 3. 网络文件传输 服务端 TF_TCPServer.py代码 运行效果(后面加了远程功能,效果图暂时还在本地) 4. 网络聊天室 服务端 UDPServer.py代码 客户端 UDPClient.py代码 运

    2024年02月01日
    浏览(45)
  • 学习网络编程No.4【socket编程实战】

    北京时间:2023/8/19/23:01,耍了好几天,主要归咎于《我欲封天》这本小说,听了几个晚上之后逐渐入门,在闲暇时间又看了一下,小高潮直接来临,最终在三个昼夜下追完了,哈哈哈!没办法呀,哎!末200章有些些烂尾,结局合乎情理,总的来说优秀,毕竟耳根的名号摆在哪

    2024年02月11日
    浏览(45)
  • Unix 网络编程:Socket 状态图&编程参数

        Flags (9 bits) (aka Control bits) . Contains 9 1-bit flags NS (1 bit): ECN-nonce - concealment protection (experimental: see RFC 3540). CWR (1 bit): Congestion Window Reduced (CWR) flag is set by the sending host to indicate that it received a TCP segment with the ECE flag set and had responded in congestion control mechanism (added to header by RFC 31

    2024年02月02日
    浏览(44)
  • Go语言网络编程(socket编程)TCP

    TCP协议 TCP/IP(Transmission Control Protocol/Internet Protocol) 即传输控制协议/网间协议,是一种面向连接(连接导向)的、可靠的、基于字节流的传输层(Transport layer)通信协议,因为是面向连接的协议,数据像水流一样传输,会存在黏包问题。 TCP服务端 一个TCP服务端可以同时连接很

    2024年02月09日
    浏览(58)
  • 【网络编程】网络编程概念,socket套接字,基于UDP和TCP的网络编程

    前言: 大家好,我是 良辰丫 ,今天我们一起来学习网络编程,网络编程的基本概念,认识套接字,UDP与TCP编程.💞💞💞 🧑个人主页:良辰针不戳 📖所属专栏:javaEE初阶 🍎励志语句:生活也许会让我们遍体鳞伤,但最终这些伤口会成为我们一辈子的财富。 💦期待大家三连,关注

    2023年04月20日
    浏览(61)
  • 网络编程:TCP socket

    TCP(Transmission Control Protocol,传输控制协议)提供的是面向连接,可靠的字节流服务。即客户和服务器交换数据前,必须现在双方之间建立一个TCP连接,之后才能传输数据。并且提供超时重发,丢弃重复数据,检验数据,流量控制等功能,保证数据能从一端传到另一端。 TCP不

    2024年02月05日
    浏览(48)
  • Python Socket网络编程

    目录 Socket概念 Python Socket编程 发送接收缓冲  消息格式定义  Socket套接字,一种独立于协议的网络编程接口,就是对网络中不同主机上的应用进程之间进行双向通信的端点。 TCP把连接作为最基本的对象,每一条TCP连接都有两个端点,这种端点我们叫作套接字(socket)。 IP层

    2024年02月07日
    浏览(45)
  • Go语言网络编程(socket编程)TCP粘包

    服务端代码如下: 客户端代码如下: 将上面的代码保存后,分别编译。先启动服务端再启动客户端,可以看到服务端输出结果如下: 收到client发来的数据: Hello, Hello. How are you?Hello, Hello. How are you?Hello, Hello. How are you?Hello, Hello. How are you?Hello, Hello. How are you? 收到client发来的数

    2024年02月09日
    浏览(66)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包