当前位置: 首页 > news >正文

网站建设市场分析2015刷外链工具

网站建设市场分析2015,刷外链工具,临安区规划建设局网站,wordpress 在线浏览完整版文章请参考: TCP/IP网络编程完整版文章 文章目录第 13 章 多种 I/O 函数13.1 send & recv 函数13.1.1 Linux 中的 send & recv13.1.2 MSG_OOB:发送紧急消息13.1.3 紧急模式工作原理13.1.4 检查输入缓冲13.2 readv & writev 函数13.2.1…

完整版文章请参考:
TCP/IP网络编程完整版文章

文章目录

    • 第 13 章 多种 I/O 函数
      • 13.1 send & recv 函数
        • 13.1.1 Linux 中的 send & recv
        • 13.1.2 MSG_OOB:发送紧急消息
        • 13.1.3 紧急模式工作原理
        • 13.1.4 检查输入缓冲
      • 13.2 readv & writev 函数
        • 13.2.1 使用 readv & writev 函数
        • 13.2.2 合理使用 readv & writev 函数

第 13 章 多种 I/O 函数

13.1 send & recv 函数

13.1.1 Linux 中的 send & recv

首先看 send 函数定义:

#include <sys/socket.h>
ssize_t send(int sockfd, const void *buf, size_t nbytes, int flags);
/*
成功时返回发送的字节数,失败时返回 -1
sockfd: 表示与数据传输对象的连接的套接字和文件描述符
buf: 保存待传输数据的缓冲地址值
nbytes: 待传输字节数
flags: 传输数据时指定的可选项信息
*/

下面是 recv 函数的定义:

#include <sys/socket.h>
ssize_t recv(int sockfd, void *buf, size_t nbytes, int flags);
/*
成功时返回接收的字节数(收到 EOF 返回 0),失败时返回 -1
sockfd: 表示数据接受对象的连接的套接字文件描述符
buf: 保存接受数据的缓冲地址值
nbytes: 可接收的最大字节数
flags: 接收数据时指定的可选项参数
*/

end 和 recv 函数的最后一个参数是收发数据的可选项,该选项可以用位或(bit OR)运算符(| 运算符)同时传递多个信息。

send & recv 函数的可选项意义:

可选项(Option)含义sendrecv
MSG_OOB用于传输带外数据(Out-of-band data)OO
MSG_PEEK验证输入缓冲中是否存在接受的数据XO
MSG_DONTROUTE数据传输过程中不参照本地路由(Routing)表,在本地(Local)网络中寻找目的地OX
MSG_DONTWAIT调用 I/O 函数时不阻塞,用于使用非阻塞(Non-blocking)I/OOO
MSG_WAITALL防止函数返回,直到接收到全部请求的字节数XO

13.1.2 MSG_OOB:发送紧急消息

MSG_OOB 可选项用于创建特殊发送方法和通道以发送紧急消息。下面为 MSG_OOB 的示例代码:

oob_send.c 程序:

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <arpa/inet.h>#define BUF_SIZE 30
void error_handling(char *message);int main(int argc, char *argv[])
{int sock;struct sockaddr_in recv_adr;if (argc != 3){printf("Usage : %s <IP> <port>\n", argv[0]);exit(1);}sock = socket(PF_INET, SOCK_STREAM, 0);memset(&recv_adr, 0, sizeof(recv_adr));recv_adr.sin_family = AF_INET;recv_adr.sin_addr.s_addr = inet_addr(argv[1]);recv_adr.sin_port = htons(atoi(argv[2]));if (connect(sock, (struct sockaddr *)&recv_adr, sizeof(recv_adr)) == -1)error_handling("connect() error");write(sock, "123", strlen("123"));send(sock, "4", strlen("4"), MSG_OOB);write(sock, "567", strlen("567"));send(sock, "890", strlen("890"), MSG_OOB);close(sock);return 0;
}void error_handling(char *message)
{fputs(message, stderr);fputc('\n', stderr);exit(1);
}

oob_recv.c 程序:

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <fcntl.h>#define BUF_SIZE 30
void error_handling(char *message);
void urg_handler(int signo);int acpt_sock;
int recv_sock;int main(int argc, char *argv[])
{struct sockaddr_in recv_adr, serv_adr;int str_len, state;socklen_t serv_adr_sz;struct sigaction act;char buf[BUF_SIZE];if (argc != 2){printf("Usage : %s <port>\n", argv[0]);exit(1);}act.sa_handler = urg_handler;sigemptyset(&act.sa_mask);act.sa_flags = 0;acpt_sock = socket(PF_INET, SOCK_STREAM, 0);memset(&recv_adr, 0, sizeof(recv_adr));recv_adr.sin_family = AF_INET;recv_adr.sin_addr.s_addr = htonl(INADDR_ANY);recv_adr.sin_port = htons(atoi(argv[1]));if (bind(acpt_sock, (struct sockaddr *)&recv_adr, sizeof(recv_adr)) == -1)error_handling("bind() error");listen(acpt_sock, 5);serv_adr_sz = sizeof(serv_adr);recv_sock = accept(acpt_sock, (struct sockaddr *)&serv_adr, &serv_adr_sz);//将文件描述符 recv_sock 指向的套接字拥有者(F_SETOWN)改为把getpid函数返回值用做id的进程fcntl(recv_sock, F_SETOWN, getpid());state = sigaction(SIGURG, &act, 0); //SIGURG 是一个信号,当接收到 MSG_OOB 紧急消息时,系统产生SIGURG信号while ((str_len = recv(recv_sock, buf, sizeof(buf), 0)) != 0){if (str_len == -1)continue;buf[str_len] = 0;puts(buf);}close(recv_sock);close(acpt_sock);return 0;
}
void urg_handler(int signo)
{int str_len;char buf[BUF_SIZE];str_len = recv(recv_sock, buf, sizeof(buf) - 1, MSG_OOB);buf[str_len] = 0;printf("Urgent message: %s \n", buf);
}void error_handling(char *message)
{fputs(message, stderr);fputc('\n', stderr);exit(1);
}

编译运行:

gcc oob_send.c -o send
gcc oob_recv.c -o recv

运行结果:

在这里插入图片描述

从运行结果可以看出,send 是客户端,recv 是服务端,客户端给服务端发送消息,服务端接收完消息之后显示出来。可以从图中看出,每次运行的效果,并不是一样的。

代码中关于:

fcntl(recv_sock, F_SETOWN, getpid());

的意思是:

文件描述符 recv_sock 指向的套接字引发的 SIGURG 信号处理进程变为 getpid 函数返回值用作 ID 进程.

上述描述中的「处理 SIGURG 信号」指的是「调用 SIGURG 信号处理函数」。但是之前讲过,多个进程可以拥有 1 个套接字的文件描述符。例如,通过调用 fork 函数创建子进程并同时复制文件描述符。此时如果发生 SIGURG 信号,应该调用哪个进程的信号处理函数呢?可以肯定的是,不会调用所有进程的信号处理函数。因此,处理 SIGURG 信号时必须指定处理信号所用的进程,而 getpid 返回的是调用此函数的进程 ID 。上述调用语句指当前为处理 SIGURG 信号的主体。

输出结果,可能出乎意料:

通过 MSG_OOB 可选项传递数据时只返回 1 个字节,而且也不快

的确,通过 MSG_OOB 并不会加快传输速度,而通过信号处理函数 urg_handler 也只能读取一个字节。剩余数据只能通过未设置 MSG_OOB 可选项的普通输入函数读取。因为 TCP 不存在真正意义上的「外带数据」。实际上,MSG_OOB 中的 OOB 指的是 Out-of-band ,而「外带数据」的含义是:

通过完全不同的通信路径传输的数据

即真正意义上的 Out-of-band 需要通过单独的通信路径高速传输数据,但是 TCP 不另外提供,只利用 TCP 的紧急模式(Urgent mode)进行传输。

13.1.3 紧急模式工作原理

MSG_OOB 的真正意义在于督促数据接收对象尽快处理数据。这是紧急模式的全部内容,而 TCP 「保持传输顺序」的传输特性依然成立。TCP 的紧急消息无法保证及时到达,但是可以要求急救。下面是 MSG_OOB 可选项状态下的数据传输过程,如图:

上面是:

send(sock, "890", strlen("890"), MSG_OOB);

图上是调用这个函数的缓冲状态。如果缓冲最左端的位置视作偏移量 0 。字符 0 保存于偏移量 2 的位置。另外,字符 0 右侧偏移量为 3 的位置存有紧急指针(Urgent Pointer)。紧急指针指向紧急消息的下一个位置(偏移量加一),同时向对方主机传递以下信息:

紧急指针指向的偏移量为 3 之前的部分就是紧急消息。

也就是说,实际上只用了一个字节表示紧急消息。这一点可以通过图中用于传输数据的 TCP 数据包(段)的结构看得更清楚,如图:

TCP 数据包实际包含更多信息。TCP 头部包含如下两种信息:

  • URG=1:载有紧急消息的数据包
  • URG指针:紧急指针位于偏移量为 3 的位置。

指定 MSG_OOB 选项的数据包本身就是紧急数据包,并通过紧急指针表示紧急消息所在的位置。

紧急消息的意义在于督促消息处理,而非紧急传输形式受限的信息。

13.1.4 检查输入缓冲

同时设置 MSG_PEEK 选项和 MSG_DONTWAIT 选项,以验证输入缓冲是否存在接收的数据。设置 MSG_PEEK 选项并调用 recv 函数时,即使读取了输入缓冲的数据也不会删除。因此,该选项通常与 MSG_DONTWAIT 合作,用于以非阻塞方式验证待读数据存在与否。下面的示例是二者的含义:

peek_recv.c 程序:

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <arpa/inet.h>#define BUF_SIZE 30
void error_handling(char *message);int main(int argc, char *argv[])
{int acpt_sock, recv_sock;struct sockaddr_in acpt_adr, recv_adr;int str_len, state;socklen_t recv_adr_sz;char buf[BUF_SIZE];if (argc != 2){printf("Usage : %s <port>\n", argv[0]);exit(1);}acpt_sock = socket(PF_INET, SOCK_STREAM, 0);memset(&acpt_adr, 0, sizeof(acpt_adr));acpt_adr.sin_family = AF_INET;acpt_adr.sin_addr.s_addr = htonl(INADDR_ANY);acpt_adr.sin_port = htons(atoi(argv[1]));if (bind(acpt_sock, (struct sockaddr *)&acpt_adr, sizeof(acpt_adr)) == -1)error_handling("bind() error");listen(acpt_sock, 5);recv_adr_sz = sizeof(recv_adr);recv_sock = accept(acpt_sock, (struct sockaddr *)&recv_adr, &recv_adr_sz);while (1){//保证就算不存在待读取数据也不会阻塞str_len = recv(recv_sock, buf, sizeof(buf) - 1, MSG_PEEK | MSG_DONTWAIT);if (str_len > 0)break;}buf[str_len] = 0;printf("Buffering %d bytes : %s \n", str_len, buf);//再次调用 recv 函数,这一次没有设置任何可选项,所以可以直接从缓冲区读出str_len = recv(recv_sock, buf, sizeof(buf) - 1, 0);buf[str_len] = 0;printf("Read again: %s \n", buf);close(acpt_sock);close(recv_sock);return 0;
}void error_handling(char *message)
{fputs(message, stderr);fputc('\n', stderr);exit(1);
}

peek_send.c 程序:

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <arpa/inet.h>
void error_handling(char *message);int main(int argc, char *argv[])
{int sock;struct sockaddr_in send_adr;if (argc != 3){printf("Usage : %s <IP> <port>\n", argv[0]);exit(1);}sock = socket(PF_INET, SOCK_STREAM, 0);memset(&send_adr, 0, sizeof(send_adr));send_adr.sin_family = AF_INET;send_adr.sin_addr.s_addr = inet_addr(argv[1]);send_adr.sin_port = htons(atoi(argv[2]));if (connect(sock, (struct sockaddr *)&send_adr, sizeof(send_adr)) == -1)error_handling("connect() error");write(sock, "123", strlen("123"));close(sock);return 0;
}void error_handling(char *message)
{fputs(message, stderr);fputc('\n', stderr);exit(1);
}

编译运行:

在这里插入图片描述

可以通过结果验证,仅发送了一次的数据被读取了 2 次,因为第一次调用 recv 函数时设置了 MSG_PEEK 可选项。

13.2 readv & writev 函数

13.2.1 使用 readv & writev 函数

readv & writev 函数的功能可概括如下:

对数据进行整合传输及发送的函数

也就是说,通过 writev 函数可以将分散保存在多个缓冲中的数据一并发送,通过 readv 函数可以由多个缓冲分别接收。因此,适用这 2 个函数可以减少 I/O 函数的调用次数。下面先介绍 writev 函数。

#include <sys/uio.h>
ssize_t writev(int filedes, const struct iovec *iov, int iovcnt);
/*
成功时返回发送的字节数,失败时返回 -1
filedes: 表示数据传输对象的套接字文件描述符。但该函数并不仅限于套接字,因此,可以像 read 一样向向其传递文件或标准输出描述符.
iov: iovec 结构体数组的地址值,结构体 iovec 中包含待发送数据的位置和大小信息
iovcnt: 向第二个参数传递数组长度
*/

上述第二个参数中出现的数组 iovec 结构体的声明如下:

struct iovec
{void *iov_base; //缓冲地址size_t iov_len; //缓冲大小
};

下图是该函数的使用方法:

writev 的第一个参数,是文件描述符,因此向控制台输出数据,ptr 是存有待发送数据信息的 iovec 数组指针。第三个参数为 2,因此,从 ptr 指向的地址开始,共浏览 2 个 iovec 结构体变量,发送这些指针指向的缓冲数据。

下面是 writev 函数的使用方法:

#include <stdio.h>
#include <sys/uio.h>int main(int argc, char *argv[])
{struct iovec vec[2];char buf1[] = "ABCDEFG";char buf2[] = "1234567";int str_len;vec[0].iov_base = buf1;vec[0].iov_len = 3;vec[1].iov_base = buf2;vec[1].iov_len = 4;str_len = writev(1, vec, 2);puts("");printf("Write bytes: %d \n", str_len);return 0;
}

结果:

ABC1234
Write bytes: 7

readv 函数,功能和 writev 函数正好相反.函数为:

#include <sys/uio.h>
ssize_t readv(int filedes, const struct iovc *iov, int iovcnt);
/*
成功时返回接收的字节数,失败时返回 -1
filedes: 表示数据传输对象的套接字文件描述符。但该函数并不仅限于套接字,因此,可以像 write 一样向向其传递文件或标准输出描述符.
iov: iovec 结构体数组的地址值,结构体 iovec 中包含待数据保存的位置和大小信息
iovcnt: 第二个参数中数组的长度
*/

下面是示例代码:

readv.c 程序:

#include <stdio.h>
#include <sys/uio.h>
#define BUF_SIZE 100int main(int argc, char *argv[])
{struct iovec vec[2];char buf1[BUF_SIZE] = {0,};char buf2[BUF_SIZE] = {0,};int str_len;vec[0].iov_base = buf1;vec[0].iov_len = 5;vec[1].iov_base = buf2;vec[1].iov_len = BUF_SIZE;str_len = readv(0, vec, 2);printf("Read bytes: %d \n", str_len);printf("First message: %s \n", buf1);printf("Second message: %s \n", buf2);return 0;
}

运行结果:

在这里插入图片描述

从图上可以看出,首先截取了长度为 5 的数据输出,然后再输出剩下的。

13.2.2 合理使用 readv & writev 函数

实际上,能使用该函数的所有情况都适用。例如,需要传输的数据分别位于不同缓冲(数组)时,需要多次调用 write 函数。此时可通过 1 次 writev 函数调用替代操作,当然会提高效率。同样,需要将输入缓冲中的数据读入不同位置时,可以不必多次调用 read 函数,而是利用 1 次 readv 函数就能大大提高效率。

其意义在于减少数据包个数。假设为了提高效率在服务器端明确禁用了 Nagle 算法。其实 writev 函数在不采用 Nagle 算法时更有价值,如图:


文章转载自:
http://laryngectomy.c7629.cn
http://fatso.c7629.cn
http://confluent.c7629.cn
http://arrestant.c7629.cn
http://manipulate.c7629.cn
http://tumescence.c7629.cn
http://osteologist.c7629.cn
http://intimate.c7629.cn
http://thinkpad.c7629.cn
http://unload.c7629.cn
http://tarnation.c7629.cn
http://chrysographed.c7629.cn
http://retrofire.c7629.cn
http://unplausible.c7629.cn
http://ovulation.c7629.cn
http://destructor.c7629.cn
http://multiprogramming.c7629.cn
http://vibrometer.c7629.cn
http://synthomycin.c7629.cn
http://cantle.c7629.cn
http://planetabler.c7629.cn
http://criminy.c7629.cn
http://racquetball.c7629.cn
http://ui.c7629.cn
http://down.c7629.cn
http://exocyclic.c7629.cn
http://sanguinariness.c7629.cn
http://exocoeiom.c7629.cn
http://passionflower.c7629.cn
http://ambience.c7629.cn
http://alexandria.c7629.cn
http://severance.c7629.cn
http://subnarcotic.c7629.cn
http://shortbread.c7629.cn
http://megohmmeter.c7629.cn
http://teleplasm.c7629.cn
http://skatebarrow.c7629.cn
http://dna.c7629.cn
http://sodality.c7629.cn
http://friarly.c7629.cn
http://peronism.c7629.cn
http://witted.c7629.cn
http://portapak.c7629.cn
http://vfat.c7629.cn
http://needlestone.c7629.cn
http://flatcar.c7629.cn
http://normal.c7629.cn
http://devilled.c7629.cn
http://anachronic.c7629.cn
http://magnetohydrodynamic.c7629.cn
http://vent.c7629.cn
http://rentable.c7629.cn
http://tenet.c7629.cn
http://skulduggery.c7629.cn
http://numerator.c7629.cn
http://pendulous.c7629.cn
http://traditional.c7629.cn
http://unwearable.c7629.cn
http://sonable.c7629.cn
http://sudamina.c7629.cn
http://decimet.c7629.cn
http://cassel.c7629.cn
http://cheliform.c7629.cn
http://perambulator.c7629.cn
http://inadvertency.c7629.cn
http://acupressure.c7629.cn
http://dimuon.c7629.cn
http://amatory.c7629.cn
http://tridactyl.c7629.cn
http://worth.c7629.cn
http://serotoninergic.c7629.cn
http://booky.c7629.cn
http://spousal.c7629.cn
http://pyrrhonism.c7629.cn
http://mumm.c7629.cn
http://animate.c7629.cn
http://signaling.c7629.cn
http://fabricator.c7629.cn
http://assigner.c7629.cn
http://overblouse.c7629.cn
http://hekate.c7629.cn
http://persulphate.c7629.cn
http://distillment.c7629.cn
http://osteometrical.c7629.cn
http://adscription.c7629.cn
http://intimidatory.c7629.cn
http://unnotched.c7629.cn
http://inebriation.c7629.cn
http://wobbulator.c7629.cn
http://decaliter.c7629.cn
http://memorandum.c7629.cn
http://pseudomonas.c7629.cn
http://gallophobe.c7629.cn
http://furrow.c7629.cn
http://laigh.c7629.cn
http://hellgramite.c7629.cn
http://mucro.c7629.cn
http://desulfuration.c7629.cn
http://cruor.c7629.cn
http://awheel.c7629.cn
http://www.zhongyajixie.com/news/89456.html

相关文章:

  • 自己做网站和外包品牌推广工作内容
  • 网站建设的设备长沙网络推广外包费用
  • 手机平台网站开发广告联盟平台哪个好
  • 龙岩做网站开发哪家厉害太原网站优化
  • 网站策划的内容网页优化公司
  • 安装wordpress主题网站关键词优化办法
  • 购物网站的图片轮播怎么做快速排名怎么做
  • 沈阳建设工程管理中心上海百度seo
  • 青白江区网站开发招聘百度热搜榜第一
  • 做网站和自媒体哪个好大连seo网站推广
  • 无忧网站模板辽宁网站建设
  • 专做艺术圈的网站seo技术代理
  • 天津市精神文明建设委员会网站网站排名优化外包
  • wordpress自定义字段面板昆明seo工资
  • 外贸接单网站排名榜在线培训考试系统
  • 网站推广策划思路是什么企业网站制作流程
  • 基于webform的网站开发下载微信
  • 天河网站建设专家怎么找平台推广自己的产品
  • html5网站开发demobt种子万能搜索神器
  • 下什么软件做网站网络营销实施方案
  • 网站建设项目详情百度快照优化
  • 织梦网站如何做伪静态推广方案有哪些
  • 网页作业班级网站怎么做排名公式
  • 购物网站设计毕业论文企业邮箱登录
  • 做网站买一个域名就够了吗专业推广引流团队
  • 婚恋网站做期货现货贵金属的人自动seo系统
  • 如何做淘客发单网站推广普通话奋进新征程
  • 男女做的那个视频网站2021搜索引擎排名
  • 电子商务网站规划的原则域名买卖交易平台
  • 制作个网站九易建网站的建站流程