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

网站建设云服务器与虚拟主机seo营销论文

网站建设云服务器与虚拟主机,seo营销论文,最流行的网络营销方式,珠海做网站哪间好1 基本概念 设置套接字的选项对套接字进行控制除了设置选项外,还可以获取选项选项的概念相当于属性,所以套接字选项也可说是套接字属性有些选项(属性)只可获取,不可设置;有些选项既可设置也可获取 2 选项…

1 基本概念

  • 设置套接字的选项对套接字进行控制
  • 除了设置选项外,还可以获取选项
  • 选项的概念相当于属性,所以套接字选项也可说是套接字属性
  • 有些选项(属性)只可获取,不可设置;
  • 有些选项既可设置也可获取

2 选项的级别

一些选项都是针对一种特定的协议
一些选项适用于所有类型的套接字
选项级别(level)的概念

2.1 常用的级别

SOL_SOCKET该级别的选项只作用于套接字本身
SOL_LRLMP该级别的选项作用于IrDA协议
IPPROTO_IP该级别的选项作用于IPv4协议
IPPROTO_IPV6该级别的选项作用于IPv6协议
IPPROTO_RM该级别的选项作用于可靠的多播传输
IPPROTO_TCP该级别的选项适用于流式套接字
IPPROTO_UDP该级别的选项适用于数据报套接字

2.2 SOL_SOCKET的常用选项

选项名称说明获取/设置
SO_ACCEPTCONN套接字是否处于监听状态获取
SO_BROADCAST允许发送广播数据两者都可
SO_DEBUG允许调试两者都可
SO_DONTROUTE不查找路由两者都可
SO_ERROR获得套接字错误获取
SO_KEEPALIVE保活连接两者都可
SO_LINGER延迟关闭连接两者都可
SO_OOBINLINE带外数据放入正常数据流两者都可
SO_RCVBUF接收缓冲区大小两者都可
SO_SNDBUF发送缓冲区大小两者都可
SO_REUSERADDR允许重用本地地址和端口两者都可
SO_TYPE获得套接字类型获取

2.3 IPPROTO_IP级别的常用选项

选项名称说明获取/设置
IP_OPTIONS获取或设置IP头部内的选项两者都可
IP_HDRINCL是否将IP头部与数据一起提交给Winsock函数两者都可
IP_TTLIP TTL相关两者都可

3获取套接字选项

3.1 getsockopt函数

#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
int getsockopt(int sockfd, int level, int optname, void *optval, socklen_t *optlen);

参数
sockfd:套接字描述符
level:表示选项的级别
optname:表示要获取的选项名称
optval:指向存放接收到的选项内容的缓冲区
optlen:指向optval所指缓冲区的大小
函数返回值:
执行成功返回0,否则返回‒1errno来获取错误码
常见的错误码:
EBADF:参数sockfd不是有效的文件描述符
EFAULT:参数optlen太小或optval所指缓冲区非法
EINVAL:参数level未知或非法
ENOPROTOOPT:选项未知或不被指定的协议族所支持
ENOTSOCK:描述符不是一个套接字描述符

3.2 示例:获取流套接字和数据报套接字接收和发送的(内核)缓冲区大小

#include <stdio.h>
#include <sys/time.h>
#include <sys/types.h>          
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <sys/ioctl.h>int main()
{int err,s = socket(AF_INET, SOCK_STREAM, 0);//创建流套接字if (s == -1) {printf("Error at socket()\n");return -1;}int su = socket(AF_INET, SOCK_DGRAM, 0); //创建数据报套接字if (s == -1) {printf("Error at socket()\n");return -1;}int optVal;int optLen = sizeof(optVal);//获取流套接字接收缓冲区大小if (getsockopt(s, SOL_SOCKET, SO_RCVBUF, (char*)&optVal,(socklen_t *)&optLen) == -1)printf("getsockopt failed:%d", errno);elseprintf("Size of stream socket receive buffer: %ld bytes\n", optVal);//获取流套接字发送缓冲区大小if (getsockopt(s, SOL_SOCKET, SO_SNDBUF, (char*)&optVal,(socklen_t *)&optLen) == -1)printf("getsockopt failed:%d", errno);else printf("Size of streaming socket send buffer: %ld bytes\n", optVal);//获取数据报套接字接收缓冲区大小if (getsockopt(su, SOL_SOCKET, SO_RCVBUF, (char*)&optVal,(socklen_t *)&optLen) == -1)printf("getsockopt failed:%d", errno);elseprintf("Size of datagram socket receive buffer: %ld bytes\n", optVal);//获取数据报套接字发送缓冲区大小if (getsockopt(su, SOL_SOCKET, SO_SNDBUF, (char*)&optVal,(socklen_t *)&optLen) == -1)printf("getsockopt failed:%d", errno);elseprintf("Size of datagram socket send buffer:%ld bytes\n", optVal);getchar();return 0;
}

3.3 示例:获取当前套接字类型

#include <stdio.h>
#include <assert.h>
#include <sys/time.h>
#include <sys/types.h>          
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <sys/ioctl.h>int main()
{int err;int s = socket(AF_INET, SOCK_STREAM, 0); //创建流套接字if (s == -1) {printf("Error at socket()\n");return -1;}int su = socket(AF_INET, SOCK_DGRAM, 0); //创建数据报套接字if (s == -1) {printf("Error at socket()\n");return -1;}int optVal;int optLen = sizeof(optVal);//获取套接字s的类型if (getsockopt(s, SOL_SOCKET, SO_TYPE, (char*)&optVal, (socklen_t *)&optLen) == -1)printf("getsockopt failed:%d", errno);else{if (SOCK_STREAM == optVal) // SOCK_STREAM宏定义值为1printf("The current socket is a stream socket.\n"); //当前套接字是流套接字else if (SOCK_DGRAM == optVal) // SOCK_ DGRAM宏定义值为2printf("The current socket is a datagram socket.\n");//当前套接字是数据报套接字}//获取套接字su的类型if (getsockopt(su, SOL_SOCKET, SO_TYPE, (char*)&optVal, (socklen_t *)&optLen) == -1)printf("getsockopt failed:%d", errno);else{if (SOCK_STREAM == optVal)  // SOCK_STREAM宏定义值为1printf("The current socket is a stream socket.\n");else if (SOCK_DGRAM == optVal) // SOCK_ DGRAM宏定义值为2printf("The current socket is a datagram socket.\n");}getchar();return 0;
}

3.4 示例:判断套接字是否处于监听状态

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <sys/time.h>
#include <sys/types.h>          
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <sys/ioctl.h>typedef struct sockaddr Addr;
typedef struct sockaddr_in Addr_in;#define ErrExit(msg) do { perror(msg); exit(EXIT_FAILURE); } while (0)int main(int argc, char *argv[])
{Addr_in service;if(argc < 3){printf("%s[ADDR][PORT]\n", argv[0]);exit(0);}int s = socket(AF_INET, SOCK_STREAM, 0); //创建一个流套接字if (s == -1) ErrExit("socket");//允许地址的立即重用char on = 1;setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));service.sin_family = AF_INET;service.sin_addr.s_addr = inet_addr(argv[1]);service.sin_port = htons( atoi(argv[2]) );if (bind(s, (Addr*)&service, sizeof(service)) == -1) //绑定套接字ErrExit("bind");int optVal;int optLen = sizeof(optVal);//获取选项SO_ACCEPTCONN的值if (getsockopt(s, SOL_SOCKET, SO_ACCEPTCONN, (char*)&optVal, (socklen_t*)&optLen) == -1)printf("getsockopt failed:%d",errno);else printf("Before listening, The value of SO_ACCEPTCONN:%d, The socket is not listening\n", optVal);// 开始侦听if (listen(s, 100) == -1)ErrExit("listen");//获取选项SO_ACCEPTCONN的值if (getsockopt(s, SOL_SOCKET, SO_ACCEPTCONN, (char*)&optVal, (socklen_t*)&optLen) == -1)ErrExit("getsockopt");else printf("After listening,The value of SO_ACCEPTCONN:%d, The socket is listening\n", optVal);return 0;
}

4 设置套接字选项

4.1 setsockopt函数

int setsockopt(int sockfd, int level, int optname, const void *optval, socklen_t optlen);

参数
sockfd:套接字描述符
level:表示选项的级别
optname:表示要获取的选项名称
optval:指向存放接收到的选项内容的缓冲区
optlen:指向optval所指缓冲区的大小
函数返回值:
执行成功返回0,否则返回‒1errno来获取错误码

4.2 示例:启用套接字的保活机制**

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <sys/time.h>
#include <sys/types.h>          
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <sys/ioctl.h>typedef struct sockaddr Addr;
typedef struct sockaddr_in Addr_in;#define ErrExit(msg) do { perror(msg); exit(EXIT_FAILURE); } while (0)int main(int argc, char *argv[])
{Addr_in service;if(argc < 3){printf("%s[ADDR][PORT]\n", argv[0]);exit(0);}int s = socket(AF_INET, SOCK_STREAM, 0); //创建一个流套接字if( s < 0)ErrExit("socket");char on = 1;setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));service.sin_family = AF_INET;service.sin_addr.s_addr = inet_addr(argv[1]);service.sin_port = htons(atoi(argv[2]));if (bind(s, (Addr *) &service, sizeof(service)) == -1) //绑定套接字ErrExit("bind");int optVal = 1;//一定要初始化int optLen = sizeof(int);//获取选项SO_KEEPALIVE的值if (getsockopt(s, SOL_SOCKET, SO_KEEPALIVE, (char*)&optVal, (socklen_t *)&optLen) == -1)ErrExit("getsockopt");else printf("After listening,the value of SO_ACCEPTCONN:%d\n", optVal);optVal = 1;if (setsockopt(s, SOL_SOCKET, SO_KEEPALIVE, (char*)&optVal, optLen) != -1)printf("Successful activation of keep alive mechanism.\n");//启用保活机制成功if (getsockopt(s, SOL_SOCKET, SO_KEEPALIVE, (char*)&optVal, (socklen_t *)&optLen) == -1)ErrExit("getsockopt");else printf("After setting,the value of SO_KEEPALIVE:%d\n", optVal);return 0;
}

5 综合示例

server.c

#include "net.h"
#include <sys/select.h>
#define MAX_SOCK_FD 1024void setKeepAlive (int sockfd, int attr_on, socklen_t idle_time, socklen_t interval, socklen_t cnt)
{setsockopt (sockfd, SOL_SOCKET, SO_KEEPALIVE, (const char *) &attr_on, sizeof (attr_on));setsockopt (sockfd, SOL_TCP, TCP_KEEPIDLE, (const char *) &idle_time, sizeof (idle_time));setsockopt (sockfd, SOL_TCP, TCP_KEEPINTVL, (const char *) &interval, sizeof (interval));setsockopt (sockfd, SOL_TCP, TCP_KEEPCNT, (const char *) &cnt, sizeof (cnt));
}int main(int argc, char *argv[])
{int i, ret, fd, newfd;fd_set set, tmpset;Addr_in clientaddr;socklen_t clientlen = sizeof(Addr_in);/*检查参数,小于3个 直接退出进程*/Argment(argc, argv);/*创建已设置监听模式的套接字*/fd = CreateSocket(argv);FD_ZERO(&set);FD_ZERO(&tmpset);FD_SET(fd, &set);while(1){tmpset = set;if( (ret = select(MAX_SOCK_FD, &tmpset, NULL, NULL, NULL)) < 0){perror("select");getchar();}if(FD_ISSET(fd, &tmpset) ){/*接收客户端连接,并生成新的文件描述符*/if( (newfd = accept(fd, (Addr *)&clientaddr, &clientlen) ) < 0){perror("accept");getchar();}
#if 1int keepAlive = 1;			//设定KeepAliveint keepIdle = 5;			//开始首次KeepAlive探测前的TCP空闭时间int keepInterval = 5;		//两次KeepAlive探测间的时间间隔int keepCount = 3;			//判定断开前的KeepAlive探测次数setKeepAlive (newfd, keepAlive, keepIdle, keepInterval, keepCount);
#endifprintf("[%s:%d]已建立连接\n", inet_ntoa(clientaddr.sin_addr), ntohs(clientaddr.sin_port));FD_SET(newfd, &set);}else{ //处理客户端数据for(i = fd + 1; i < MAX_SOCK_FD; i++){if(FD_ISSET(i, &tmpset)){if( DataHandle(i) <= 0){if( getpeername(i, (Addr *)&clientaddr, &clientlen) )perror("getpeername");printf("[%s:%d]断开连接\n", inet_ntoa(clientaddr.sin_addr), ntohs(clientaddr.sin_port));FD_CLR(i, &set);close(i);}}}}}close(fd);return 0;
}

socket.c

#include "net.h"void Argment(int argc, char *argv[]){if(argc < 3){fprintf(stderr, "%s<addr><port>\n", argv[0]);exit(0);}
}
int CreateSocket(char *argv[]){/*创建套接字*/int fd = socket(AF_INET, SOCK_STREAM, 0);if(fd < 0)ErrExit("socket");/*允许地址快速重用*/int flag = 1;if( setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &flag, sizeof(flag) ) )perror("setsockopt");/*设置通信结构体*/Addr_in addr;bzero(&addr, sizeof(addr) );addr.sin_family = AF_INET;addr.sin_port = htons( atoi(argv[2]) );/*绑定通信结构体*/if( bind(fd, (Addr *)&addr, sizeof(Addr_in) ) )ErrExit("bind");/*设置套接字为监听模式*/if( listen(fd, BACKLOG) )ErrExit("listen");return fd;
}
int DataHandle(int fd){char buf[BUFSIZ] = {};Addr_in peeraddr;socklen_t peerlen = sizeof(Addr_in);if( getpeername(fd, (Addr *)&peeraddr, &peerlen) )perror("getpeername");int ret = recv(fd, buf, BUFSIZ, 0);if(ret < 0)perror("recv");if(ret > 0){printf("[%s:%d]data: %s\n", inet_ntoa(peeraddr.sin_addr), ntohs(peeraddr.sin_port), buf);}return ret;
}

net.h

`#ifndef _NET_H_
#define _NET_H_#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <strings.h>
#include <errno.h>typedef struct sockaddr Addr;
typedef struct sockaddr_in Addr_in;
#define BACKLOG 5
#define ErrExit(msg) do { perror(msg); exit(EXIT_FAILURE); } while(0)void Argment(int argc, char *argv[]);
int CreateSocket(char *argv[]);
int DataHandle(int fd);#endif

通过wireshark查看设置keepalive的包
在这里插入图片描述

6 练习

编程实现带保活连接功能的TCP代码,要求开始首次KeepAlive探测前的TCP空闭时间为3秒,两次KeepAlive探测间的时间间隔为3次,判定断开前的KeepAlive探测次数为7次。提交代码和完成通信的截图
注意:部分操作系统需要添加额外头文件 netinet/tcp.h

#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <netinet/tcp.h>#define MAX_SOCK_FD 1024
#define BACKLOG 5#define ErrExit(msg) do{perror(msg); exit(EXIT_FAILURE);} while(0)void SetKeepAlive(int sockfd,int attr_on, socklen_t idle_time, socklen_t interval, socklen_t cnt)
{setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, (const char *) &attr_on, sizeof(attr_on));setsockopt(sockfd, SOL_TCP, TCP_KEEPIDLE, (const char *) &idle_time, sizeof(idle_time));setsockopt(sockfd, SOL_TCP, TCP_KEEPINTVL, (const char *) &interval, sizeof(interval));setsockopt(sockfd, SOL_TCP, TCP_KEEPCNT, (const char *) &cnt, sizeof(cnt));
}int DataHandle(int fd)
{char buf[BUFSIZ] = {};int ret;struct sockaddr_in peeraddr;socklen_t peerlen = sizeof(struct sockaddr_in);if(getpeername(fd, (struct sockaddr *)&peeraddr, &peerlen) )perror("getpeername");ret = recv(fd, buf, BUFSIZ, 0);if(ret < 0){perror("recv");}if( ret > 0){printf("[%s:%d]data: %s\n", inet_ntoa(peeraddr.sin_addr), ntohs(peeraddr.sin_port), buf);}return ret;
}int main(int argc,char *argv[])
{int fd, new_fd, i ,ret;fd_set set, tmpset;struct sockaddr_in addr, client_addr;socklen_t clientlen = sizeof(client_addr);int flag = 1;if(argc < 3){printf("%s <addr> <port>\n",argv[0]);exit(0);}//create socketfd = socket(AF_INET, SOCK_STREAM, 0);if(fd < 0){ErrExit("socket");}//avoids the error of ports being occupiedif( setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &flag, sizeof(flag) ) ){perror("setsockopt");}//init struct sockaddr_inmemset(&addr, 0, sizeof(addr));addr.sin_family = AF_INET;addr.sin_port = htons( atoi(argv[2]));if (inet_aton(argv[1], &addr.sin_addr) == 0){printf("Invalid address\n");exit(EXIT_FAILURE);}//bindif(bind(fd, (struct sockaddr *) &addr, sizeof(struct sockaddr_in)) == -1){ErrExit("bind");}//listenif(listen(fd, BACKLOG) == -1){ErrExit("listen");}//selectFD_ZERO(&set);FD_ZERO(&tmpset);FD_SET(fd, &set);while(1){tmpset = set;if((ret =  select(MAX_SOCK_FD, &tmpset,NULL,NULL,NULL)) < 0){ErrExit("select");}if(FD_ISSET(fd, &tmpset) > 0){new_fd = accept(fd,(struct sockaddr *)&client_addr,&clientlen);if(new_fd < 0){perror("accept");}#if 1int keepAlive = 1;int keepIdle = 3;int keepInterval = 3;int keepCount = 7;SetKeepAlive(new_fd, keepAlive, keepIdle, keepInterval, keepCount);
#endif printf("[%s:%d]connected\n",inet_ntoa(client_addr.sin_addr),\ntohs(client_addr.sin_port));FD_SET(new_fd, &set);}else //if(FF_ISSET(fd, &tmpset < 0)  //handle client{for(i = fd + 1; i < MAX_SOCK_FD; i++){// can readif(FD_ISSET(i,&tmpset)){if(DataHandle(i) <= 0){if(getpeername(i,(struct sockaddr *)&client_addr,&clientlen))			perror("getpeername");printf("[%s:%d]disconnected\n",inet_ntoa(client_addr.sin_addr),\ntohs(client_addr.sin_port));FD_CLR(i,&set);  }}}}}close(fd);return 0;
}
http://www.qdjiajiao.com/news/6653.html

相关文章:

  • 长春哪里有做网站的全网营销系统
  • 学校网站群建设 ppt百度搜索词排名
  • wordpress 插件系统标题优化
  • 网站建设报价明细表关键词优化排名软件怎么样
  • 厦门建站服务百度网站优化软件
  • 网站管理是什么工作重庆森林粤语
  • 招商加盟网站建设目的深圳网络推广软件
  • 怎么做网站优化 s最新热点新闻事件
  • 怎么样提高网站点击率全网引流推广 价格
  • 免费网站封装app灰色词快速排名方法
  • 各种网站底部图标代码站长之家 seo查询
  • 网站加载速度合肥关键词排名技巧
  • 县政府网站问题建设调研报告被逆冬seo课程欺骗了
  • 郑州专做喜宴的网站如何做好网络宣传工作
  • 业绩统计网站开发联赛积分榜排名
  • 做门户网站用什么模板好郑州抖音seo
  • 织里网站建设网站域名查询工具
  • 初中上哪个网站找题做移动建站优化
  • 搭建一个自己的网站昆明做网站的公司
  • 现代网站建设公司精准客源app
  • 网站建设 设计电脑上突然出现windows优化大师
  • 网站建设 经济效益百度竞价代运营外包
  • 网站链接做app新闻发布最新新闻
  • 绵阳汽车网站制作网络优化行业的发展前景
  • 哪家公司做网站结算好济南竞价托管公司
  • 西安便宜做网站今日的新闻
  • 网站永久镜像怎么做上海网站排名seo公司哪家好
  • 南京做网站工作室专门制作小程序的公司
  • asp.net实用网站开发doc推广普通话手抄报内容怎么写
  • 招标网站建设方案app开发