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

优秀购物网站房产资讯什么网站做的好

优秀购物网站,房产资讯什么网站做的好,手机网站建设服务商,注册门户网站Socket 是网络协议栈暴露给编程人员的 API,相比复杂的计算机网络协议,API 对关键操作和配置数据进行了抽象,简化了程序编程。 本文讲述的 socket 内容源自 Linux man。本文主要对各 API 进行详细介绍,从而更好的理解 socket 编程。…

         Socket 是网络协议栈暴露给编程人员的 API,相比复杂的计算机网络协议,API 对关键操作和配置数据进行了抽象,简化了程序编程。

        本文讲述的 socket 内容源自 Linux man。本文主要对各 API 进行详细介绍,从而更好的理解 socket 编程。


send

send()           遵循 POSIX.1 - 2008

MSG_CONFIRM 是 Linux 扩展

1.库

标准 c 库,libc, -lc

2.头文件

<sys/socket.h>

3.接口定义

       ssize_t send(int sockfd, const void buf[.len], size_t len, int flags);ssize_t sendto(int sockfd, const void buf[.len], size_t len, int flags,const struct sockaddr *dest_addr, socklen_t addrlen);ssize_t sendmsg(int sockfd, const struct msghdr *msg, int flags);

4.接口描述

        send()、sendto()、sendmsg() 调用用来向另一个套接字发送消息。

        send() 通常只能用在连接状态(即接收者已知)的套接字上,send() 和 write(2) 的唯一不同是 send() 存在 flags 标记。当标记为 0 时,send() 和 write(2) 等效。同样的,下面的两个调用也是等效的。

           send(sockfd, buf, len, flags);
           sendto(sockfd, buf, len, flags, NULL, 0);

         sockfd 参数是 发送套接字的文件描述符。

        如果sendto() 用在连接模式(SOCK_STREAM、SOCK_SEQPACKET)的套接字上,那么参数 dest_addr 和 addrlen 将被忽略(当它们不是 NULL 或者 0时,会返回 EISCON 错误),并且当套接字没有连接时,会返回 ENOTCONN 错误。否则需要给定 addrlen 指定长度的 dest_addr 目标地址,目标地址由 msg.msg_name 给定,长度是 msg.msg_namelen 指定。

        对于 send() 和 sendto(),发送的消息放在 len 长度的 buf 中。对于 sendmsg(),消息由 msg.msg_iov 数组元素指定,sendmsg() 调用同时允许发送一些辅助数据(也称为控制信息)。

        如果消息太大以至于不能自动的透传给底层协议,调用会返回  EMSGSIZE 错误,该消息不会被发送。

        send() 调用没有显示的关于传输失败的指示,在内部检测到这类错误时也只会返回 -1。

        当消息不能装进套接字的发送缓冲区时,send() 正常会阻塞,除非套接字放进了非阻塞 I/O 模式,这种情况在非阻塞模式下会报告 EAGAIN 或者 EWOULDBLOCK 错误。这时可以使用 select(2) 来检测什么时候可以发送更多数据。

flags 参数

        flags 参数可以是下面值的位或:

        MSG_CONFIRM(Linux 2.3.15 后)

        告诉链路层有进展发生:从对端收到了一个成功的回复。如果链路层没有收到这个,那么它通常会在骚扰邻居(通过 ARP 单播)。这个标记只在IPv4/IPv6 的 SOCK_DGRAM 和 SOCK_RAW 套接字中可用,详细信息可以参考 arp(7)。

        MSG_DONTROUTE

        不要使用向网关发送我们的数据包,只发给和我们直接连接的主机。这个通常只有诊断或者路由程序使用。这个只用于支持路由的协议家族,packet 套接字不支持。

        MSG_DONTWAIT(Linux 2.2 后)

        开启非阻塞操作。如果操作想要阻塞,那么就会返回 EAGAIN 或者 EWOULDBLOCK 错误。这个行为和设置 O_NONBLOCK 标记(通过 fcntl(2) F_SETFL 操作)行为类似,但是 MSG_DONTWAIT 只对当前调用生效,而 O_NONBLOCK 是设置到打开文件描述上(参考 open(2)),这会影响调用进程中的所有线程以及其他持有指向该打开文件描述的文件描述符的进程。

        MSG_EOR(Linux 2.2 后)

        结束一个记录(当支持该语义时,用于 SOCK_SEQPACKET 类型的套接字)

        MSG_MORE(Linux 2.4.4 后)

        调用者有更多数据要发送。这个标记用在 TCP 套接字中来获得和 TCP_CORK 套接字选项意向的效果,区别是这个标记只对当前调用生效。

        MSG_NOSIGNAL(Linux 2.2 后)

        如果对端关闭了流套接字,不要生成 SIGPIPE 信号,不过仍然会返回 EPIPE 错误。这和使用 sigaction(2) 来忽略 SIGPIPE 效果差不多,还是 MSG_NONSIGNAL 只对当前调用生效,并且忽略 SIGPIPE 设置的是进程属性,会影响进程中的所有线程。

        MSG_OOB

        在支持该带外数据的套接字(比如 SOCK_STREAM)上发送带外数据。 底层协议必须也支持带外数据传输。

         MSG_FASTOPEN(Linux 3.7 后)

        尝试 TCP 快速打开(RFC7413)并发送在 SYN 中发送数据,就像 connect(2) 和 write(2) 合并一样,进行了隐式的 connect(2) 操作。它会一直阻塞知道数据被缓存并且握手结束。对于一个非阻塞套接字,它会返回缓存数据的大小并且发送一个 SYN 包。如果本地 cookie 不可用,它会返回 EINPROGRESS,并自动发送一个 SYN 带着快速打开 cookie 请求。调用者需要在新连接的套接字上重新发送数据。发生错误时,它会在握手失败时设置和 connect(2) 相同的 errno。这个标记需要 sysctl net.ipv4.tcp_fastopen 来开启 TCP 快速打开客户端支持。

        参考 tcp(7) TCP_FASTOPEN_CONNECT 套接字选项来查看一些可选的方法。

sendmsg()

        sendmsg() 使用的 msghdr 结构定义如下:

           struct msghdr {void         *msg_name;       /* Optional address */socklen_t     msg_namelen;    /* Size of address */struct iovec *msg_iov;        /* Scatter/gather array */size_t        msg_iovlen;     /* # elements in msg_iov */void         *msg_control;    /* Ancillary data, see below */size_t        msg_controllen; /* Ancillary data buffer len */int           msg_flags;      /* Flags (unused) */};

        msg_name 字段用来指定非连接数据包类型套接字的目标地址,它指向一个包含地址的缓冲区,msg_namelen 字段应该设置为地址的大小。对于连接套接字,这些字段应该对应的设置为 NULL 和 0。   

         msg_iov 和 msg_ivolen 字段指定了 scatter-gether 区域,和 writev(2) 类似。

        我们可以使用 msg_control 和 msg_controllen 成员发送控制信息(辅助数据),内核能够处理套接字最大的控制缓冲区大小由 /proc/sys/net/core/optmem_max 指定,参考 socket(7)。对于其他域套接字关于辅助数据的信息,可以参考 unix(7) 和 ip(7)。

        msg_flags 字段忽略。        

5.返回值

        调用成功时,返回已发送数据的字节数。

        发生错误时,返回 -1,并设置errno 来指示错误类型。

       下面这些标准错误值是由套接字层生成的,其他错误可能会由底层协议模块产生并返回,具体可以参考对应的手册页。

        错误值定义如下:

EACCESS(特定于由路径指定的 UNIX 域套接字)目的套接字写权限被拒绝,或者在目录前缀下的搜索权限被拒绝        
 EAGAIN/EWOULDBLOCK套接字被设置为非阻塞,但是请求操作打算阻塞。POSIX.1-2021 允许随意哪个错误都可以,并且不假定两个值相等,所以移植程序应该对每个值都进行判断。
EAGAIN(网络域数据报套接字)sockfd 指定的套接字还没有绑定到地址,并且在尝试绑定到临时端口时,临时端口用尽了。可以看 /proc/sys/net/ipv4/ip_local_port_rang 的讨论
EALREADY另一个快速打开(Fast Open)正在进行中
EBADFsockfd 不是一个打开的文件描述
ECONNRESET对端重置了连接
EDESTADDRREQ套接字不是连接模式,并且没有设置对端地址
EFAULT参数中指定了用户空间不合法的地址
EINTR数据发送完成前有信号发生,参考 signal(7)
EINVAL参数不合法
EISCONN连接模式的套接字早已经连接过了,但是又指定了接收者。(目前要么返回这个错误,要么直接忽略掉接收者参数)
EMSGSIZE套接字类型要求消息自动发送,但是消息的大小却使得这个无法完成
ENOBUFS网络接口输出队列满了。这个通常指示接口已经停止发送,但可能导致传输堵塞。(正常情况下,这个不会在 Linux 上发生,当设备队列溢出时,数据包会偷偷的被丢掉。)
ENOMEM没有内存了
ENOTCONN套接字没连接,也没有指定目标地址
ENOTSOCKsockfd 文件描述符没有指向一个套接字
EOPNOTSUPPflags 里面有些位设置不正确
EPIPE面向连接的套接字在本地被关闭,这种情况下,进程也会收到 SIGPIP 信号,除非我们设置了 MSG_NOSIGNAL。

6.注意

       参考 sendmmsg(2) 来查阅更多 Linux 系统用于一次调用传输多个数据包的信息。

        Linux 系统可能返回 EPIPE 而不是 ENOTCONN。

7.代码

   Server program#include <netdb.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <sys/socket.h>#include <sys/types.h>#include <unistd.h>#define BUF_SIZE 500intmain(int argc, char *argv[]){int                      sfd, s;char                     buf[BUF_SIZE];ssize_t                  nread;socklen_t                peer_addrlen;struct addrinfo          hints;struct addrinfo          *result, *rp;struct sockaddr_storage  peer_addr;if (argc != 2) {fprintf(stderr, "Usage: %s port\n", argv[0]);exit(EXIT_FAILURE);}memset(&hints, 0, sizeof(hints));hints.ai_family = AF_UNSPEC;    /* Allow IPv4 or IPv6 */hints.ai_socktype = SOCK_DGRAM; /* Datagram socket */hints.ai_flags = AI_PASSIVE;    /* For wildcard IP address */hints.ai_protocol = 0;          /* Any protocol */hints.ai_canonname = NULL;hints.ai_addr = NULL;hints.ai_next = NULL;s = getaddrinfo(NULL, argv[1], &hints, &result);if (s != 0) {fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(s));exit(EXIT_FAILURE);}/* getaddrinfo() returns a list of address structures.Try each address until we successfully bind(2).If socket(2) (or bind(2)) fails, we (close the socketand) try the next address. */for (rp = result; rp != NULL; rp = rp->ai_next) {sfd = socket(rp->ai_family, rp->ai_socktype,rp->ai_protocol);if (sfd == -1)continue;if (bind(sfd, rp->ai_addr, rp->ai_addrlen) == 0)break;                  /* Success */close(sfd);}freeaddrinfo(result);           /* No longer needed */if (rp == NULL) {               /* No address succeeded */fprintf(stderr, "Could not bind\n");exit(EXIT_FAILURE);}/* Read datagrams and echo them back to sender. */for (;;) {char host[NI_MAXHOST], service[NI_MAXSERV];peer_addrlen = sizeof(peer_addr);nread = recvfrom(sfd, buf, BUF_SIZE, 0,(struct sockaddr *) &peer_addr, &peer_addrlen);if (nread == -1)continue;               /* Ignore failed request */s = getnameinfo((struct sockaddr *) &peer_addr,peer_addrlen, host, NI_MAXHOST,service, NI_MAXSERV, NI_NUMERICSERV);if (s == 0)printf("Received %zd bytes from %s:%s\n",nread, host, service);elsefprintf(stderr, "getnameinfo: %s\n", gai_strerror(s));if (sendto(sfd, buf, nread, 0, (struct sockaddr *) &peer_addr,peer_addrlen) != nread){fprintf(stderr, "Error sending response\n");}}}
   Client program#include <netdb.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <sys/socket.h>#include <sys/types.h>#include <unistd.h>#define BUF_SIZE 500intmain(int argc, char *argv[]){int              sfd, s;char             buf[BUF_SIZE];size_t           len;ssize_t          nread;struct addrinfo  hints;struct addrinfo  *result, *rp;if (argc < 3) {fprintf(stderr, "Usage: %s host port msg...\n", argv[0]);exit(EXIT_FAILURE);}/* Obtain address(es) matching host/port. */memset(&hints, 0, sizeof(hints));hints.ai_family = AF_UNSPEC;    /* Allow IPv4 or IPv6 */hints.ai_socktype = SOCK_DGRAM; /* Datagram socket */hints.ai_flags = 0;hints.ai_protocol = 0;          /* Any protocol */s = getaddrinfo(argv[1], argv[2], &hints, &result);if (s != 0) {fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(s));exit(EXIT_FAILURE);}/* getaddrinfo() returns a list of address structures.Try each address until we successfully connect(2).If socket(2) (or connect(2)) fails, we (close the socketand) try the next address. */for (rp = result; rp != NULL; rp = rp->ai_next) {sfd = socket(rp->ai_family, rp->ai_socktype,rp->ai_protocol);if (sfd == -1)continue;if (connect(sfd, rp->ai_addr, rp->ai_addrlen) != -1)break;                  /* Success */close(sfd);}freeaddrinfo(result);           /* No longer needed */if (rp == NULL) {               /* No address succeeded */fprintf(stderr, "Could not connect\n");exit(EXIT_FAILURE);}/* Send remaining command-line arguments as separatedatagrams, and read responses from server. */for (size_t j = 3; j < argc; j++) {len = strlen(argv[j]) + 1;/* +1 for terminating null byte */if (len > BUF_SIZE) {fprintf(stderr,"Ignoring long message in argument %zu\n", j);continue;}if (write(sfd, argv[j], len) != len) {fprintf(stderr, "partial/failed write\n");exit(EXIT_FAILURE);}nread = read(sfd, buf, BUF_SIZE);if (nread == -1) {perror("read");exit(EXIT_FAILURE);}printf("Received %zd bytes: %s\n", nread, buf);}exit(EXIT_SUCCESS);}
http://www.yayakq.cn/news/941777/

相关文章:

  • 外贸网站的作用做一钓鱼网站
  • 旅游网站只做陕西省建设网
  • 房产网站开发公司为企业制定网络营销方案
  • 我国空间站建造临猗商城网站建设平台
  • 保定网站制作网页如何评价企业网站推广效果?
  • 公司网站建设工作通知苏州制作手机网站
  • 云网站7china网站建设要钱吗
  • 网站域名过期怎么办可信网站证书
  • 哈尔滨企业建站服务商网站为何不显示百度商桥对话框
  • 北京网站制作长沙wordpress android api
  • 龙华网站建设的公司wordpress不能分类
  • 网站如何做浏览量网站建设 电子商务 品牌首选IDC
  • 建网站的方案html5企业网站带后台
  • 10个网站 云主机需求德州网站建设赖殿波
  • 设计专业招聘网站做网站是什么软件
  • 电子商务网站域名注册要求企业网站制作套餐
  • 微网站 开发xampp wamp wordpress
  • 恩施网站定制南宁seo管理
  • 合肥企业快速建站营销型网站效果不好
  • 网站建设项目公告wordpress密码破解
  • 英文网站设计多少钱注册wordpress
  • 品牌产品网站怎么做公司网站制作招聘
  • 网站建设微信小程序开发dw不用代码做网站
  • 网站网页压缩俄罗斯搜索引擎
  • 网站免费正能量直接进入小说平安网站建设公司
  • 廊坊做网站教程建设网站的费用明细
  • 北京做网站好的网站建设公司南京广告公司装修
  • 高碑店做网站的公司最新火车停运通知今天
  • 外包公司设计完网站谁负责运营深圳做百度网站
  • 企业营销策划 网站建设江苏省建设证书变更网站