热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

java套接字阻塞_深入分析JavaSocket原理之阻塞套接字

0、套接字(Socket)介绍0.1套接字是什么?套接字类似于unix中的管道,我们既可以往里面写数据(套接字发送缓冲区),也可以从中读取

0、套接字(Socket)介绍

0.1 套接字是什么?

套接字类似于unix中的管道,我们既可以往里面写数据(套接字发送缓冲区),也可以从中读取数据(套接字接收缓冲区);

套接字工作在传输层与应用层之间,主要是为应用程序提供网络I/O的能力;

Sockets API通过套接字描述符去定位要访问套接字文件; 比如说要写入的套接字的套接字描述符为5,那程序便可以通过描述符5去访问这个套接字文件。

0.2 简单的一次Socket通信的图:

省略一些维护缓冲区的细节:

c1526baf53afc48ecff2e9ef5ea93d20.png

即我们的程序通过fgets()将要传输的数据传入标准输入文件中,并写入套接字发送缓冲区,再经过TCP按照MSS(最大报文长度)等选项分包,再经过IP协议族的转发至服务端的相应的套接字接收缓冲区,然后复制到应用程序可以用于输出的标准输出文件中进行相应的处理。

一、一次基于TCP的网络通信的过程:

1.1 服务器启动,并准备监听:

int listenfd, connfd;

struct sockaddr_inservaddr;

char buff[MAXLINE];

//创建一个TCP套接字并返回一个套接字描述符

listenfd = Socket(AF_INET, SOCK_STREAM, 0);

//设置IPV4的套接字地址结构

bzero(&servaddr, sizeof(servaddr));

servaddr.sin_family = AF_INET;

servaddr.sin_addr.s_addr = htonl(INADDR_ANY);

servaddr.sin_port = htons(13);/* daytime server */

//按照套接字地址结构设置服务器监听信息

Bind(listenfd, (SA *) &servaddr, sizeof(servaddr));

//将套接字设置为被动打开,即处于等待客户端发起三次握手的状态

Listen(listenfd, LISTENQ);

1.2 客户端构建套接字文件并发起连接:

首先构建套接字

//存储套接字描述符,Sockets API通过此描述符对套接字文件进行操作;

int sockfd;

//使用socket函数创建网际的、面向字节流的套接字(即TCP套接字),并返回套接字描述符

if ( (sockfd &#61; socket(AF_INET, SOCK_STREAM, 0)) <0)

err_sys("socket error");

然后构建IPV4的套接字地址结构

//IPV4套接字地址结构&#xff0c;主要用于设置套接字的属性

struct sockaddr_inservaddr;

bzero(&servaddr, sizeof(servaddr));

//设置协议为网际协议&#xff0c;网际协议即为IP协议族

servaddr.sin_family &#61; AF_INET;

//设置要访问的服务器端口号为13

servaddr.sin_port &#61; htons(13);

//argv[1]是点分十进制IP&#xff0c;如192.168.0.1

//inet_pton函数将其转变为适合在网络上传输的二进制流

if (inet_pton(AF_INET, argv[1], &servaddr.sin_addr) <&#61; 0)

err_quit("inet_pton error for %s", argv[1]);

然后通过connect()函数连接服务器

//传入的参数1. sockfd为套接字描述符&#xff1b;

//2.3. IPV4套接字地址结构和结构体的长度

if (connect(sockfd, (SA *) &servaddr, sizeof(servaddr)) <0)

err_sys("connect error");

1.3 服务器接受连接并返回响应&#xff1a;

样例是比较简单的服务器&#xff0c;一次只能处理一个连接&#xff0c;再往后一点可以使用fork()函数创建新进程&#xff0c;使用线程代替进程&#xff0c;并使用线程池&#xff0c;或者改用非阻塞模式等等。

监听套接字维护着一个连接队列&#xff0c;主要用于提供给Accept()函数去处理已完成三次握手的套接字的请求&#xff1b;

fca904705152d01b502652fc049f6170.png

//监听套接字以及已连接套接字描述符

intlistenfd, connfd;

//应用进程缓冲区

charbuff[MAXLINE];

time_tticks;

for ( ; ; ) {

//调用Accept()函数处理Connect队列中已完成连接的套接字的请求

//并对已连接套接字描述符进行赋值

connfd &#61; Accept(listenfd, (SA *) NULL, NULL);

ticks &#61; time(NULL);

//向缓冲区中写要返回给客户端的数据

snprintf(buff, sizeof(buff), "%.24s\r\n", ctime(&ticks));

//将缓冲区中数据通过write()函数系统调用写入到套接字中

Write(connfd, buff, strlen(buff));

//close()函数通过四次挥手关闭与客户端的连接

Close(connfd);

}

1.4 客户端接收服务端响应并进行相应处理&#xff1a;

charrecvline[MAXLINE &#43; 1];

//调用&#96;read()函数&#96;读取套接字接收缓冲区&#xff0c;并放入recvline缓冲区中

while ( (n &#61; read(sockfd, recvline, MAXLINE)) > 0) {

recvlinbzero(&servaddr, sizeof(servaddr));

servaddr.sin_family &#61; AF_INET;

servaddr.sin_port &#61; htons(13);/* daytime server */

if (inet_pton(AF_INET, argv[1], &servaddr.sin_addr) <&#61; 0)

err_quit("inet_pton error for %s", argv[1]);

e[n] &#61; 0;/* null terminate */

//将recvline中的数据放入标准输出文件中&#xff0c;并使用I/O函数fputs()输出结果

if (fputs(recvline, stdout) &#61;&#61; EOF)

err_sys("fputs error");

}



推荐阅读
  • 本文详细解析 Skynet 的启动流程,包括配置文件的读取、环境变量的设置、主要线程的启动(如 timer、socket、monitor 和 worker 线程),以及消息队列的实现机制。 ... [详细]
  • 本文详细介绍了Socket在Linux内核中的实现机制,包括基本的Socket结构、协议操作集以及不同协议下的具体实现。通过这些内容,读者可以更好地理解Socket的工作原理。 ... [详细]
  • 如何尽量处理TIMEWAIT过多?
    如何尽量处理TIMEWAIT过多?编辑内核文件etcsysctl.conf,加入以下内容:net.ipv4.tcp_syncookies1表示开启SYNCookies。当出现SYN ... [详细]
  • 本文详细介绍如何在Spring Boot项目中集成和使用JPA,涵盖JPA的基本概念、Spring Data JPA的功能以及具体的操作步骤,帮助开发者快速掌握这一强大的持久化技术。 ... [详细]
  • 酷家乐 Serverless FaaS 产品实践探索
    本文探讨了酷家乐在 Serverless FaaS 领域的实践与经验,重点介绍了 FaaS 平台的构建、业务收益及未来发展方向。 ... [详细]
  • 本文档提供了详细的MySQL安装步骤,包括解压安装文件、选择安装类型、配置MySQL服务以及设置管理员密码等关键环节,帮助用户顺利完成MySQL的安装。 ... [详细]
  • 深入探讨Web服务器与动态语言的交互机制:CGI、FastCGI与PHP-FPM
    本文详细解析了Web服务器(如Apache、Nginx等)与动态语言(如PHP)之间通过CGI、FastCGI及PHP-FPM进行交互的具体过程,旨在帮助开发者更好地理解这些技术背后的原理。 ... [详细]
  • 本文探讨了六项Java特性,它们虽然强大,但在不当使用时可能会给应用程序带来严重问题。文章基于作者Nikita Salnikov Tarnovski多年的应用性能调优经验,提供了对这些特性的深入分析。 ... [详细]
  • 帝国cms各数据表有什么用
    CMS教程|帝国CMS帝国cmsCMS教程-帝国CMS精易编程助手源码,ubuntu桥接设置,500错误是tomcat吗,爬虫c原理,php会话包括什么,营销seo关键词优化一般多 ... [详细]
  • STM32代码编写STM32端不需要写关于连接MQTT服务器的代码,连接的工作交给ESP8266来做,STM32只需要通过串口接收和发送数据,间接的与服务器交互。串口三配置串口一已 ... [详细]
  • MongoDB高可用架构:深入解析Replica Set机制
    MongoDB的高可用架构主要依赖于其Replica Set机制。Replica Set通过多个mongod节点的协同工作,实现了数据的冗余存储和故障自动切换,确保了系统的高可用性和数据的一致性。本文将深入解析Replica Set的工作原理及其在实际应用中的配置和优化方法,帮助读者更好地理解和实施MongoDB的高可用架构。 ... [详细]
  • 公司有个系统,比较古老,web端使用的是applet,applet作为socketclient端。另一台服务器运行socketserver.当多次执行某一个特定事务时(通过Applet,该事务会触 ... [详细]
  • 时序数据是指按时间顺序排列的数据集。通过时间轴上的数据点连接,可以构建多维度报表,揭示数据的趋势、规律及异常情况。 ... [详细]
  • 深入浅出:Hadoop架构详解
    Hadoop作为大数据处理的核心技术,包含了一系列组件如HDFS(分布式文件系统)、YARN(资源管理框架)和MapReduce(并行计算模型)。本文将通过实例解析Hadoop的工作原理及其优势。 ... [详细]
  • Python 伦理黑客技术:深入探讨后门攻击(第三部分)
    在《Python 伦理黑客技术:深入探讨后门攻击(第三部分)》中,作者详细分析了后门攻击中的Socket问题。由于TCP协议基于流,难以确定消息批次的结束点,这给后门攻击的实现带来了挑战。为了解决这一问题,文章提出了一系列有效的技术方案,包括使用特定的分隔符和长度前缀,以确保数据包的准确传输和解析。这些方法不仅提高了攻击的隐蔽性和可靠性,还为安全研究人员提供了宝贵的参考。 ... [详细]
author-avatar
塞上秋雪_838
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有