服务端socket重用属性设置
初始化socket
socket是一种系统资源,并不是每次初始化都一定成功,因此为了避免初始化失败,一般使用多次初始化的方式,如下所示:
unsigned int times = 0x0;
while((server = socket(PF_INET6, SOCK_STREAM, )) < && times < 0x3)
{
times++;
printf("create socket faild %d times\n", times);
}
设置socket的可重用属性
一般来说,一个端口释放后需要等待两分钟左右才能被再次使用,SO_REUSEADDR是让端口释放后立即就可以被再次使用。例如:一个进程监听一个端口,进程在某个时候异常重启了,如果socket没有设置可重用属性,那么进程重启后就会出现bind错误,因为同一个端口两次监听的时间间隔需要75秒;如果设置了可重用属性,那么同一个端口释放之后马上就可以再次使用,如下所示:
int reuse = 0x0;
result = setsockopt(server, SOL_SOCKET, SO_REUSEADDR, (char *)&reuse, sizeof(int));
if(result != )
{
printf(" Fail to set socket reuseraddr options, errno = 0x%x!\n", result);
}
设置socket的保活属性
TCP是一种面向连接的协议,因此需要实时检查连接是否正常,特别是在上层长时间无数据传输时。一般检查连接是否正常的方式是提供一个保活机制,即定时的发送一种探测报文,可以是上层自己发送,也可以使用socket自己提供的保活机制,也就是保活属性,但是socket自己提供的保活机制一般不可靠,或者说是不完全可靠,因此在实际编程中是两种同时使用。首先上层启用一个任务,定时发送检测报文,然后设置socket的保活属性,以期达到完全可靠,如下所示:
int optval = 0x1;
result = setsockopt(server, SOL_SOCKET, SO_KEEPALIVE, (char*)&optval, sizeof(int));
if(result != )
{
printf("Fail to set socket keepalive options, errno = 0x%x!\n", result);
}
设置socket的缓冲区大小属性
调用send和recv接口操作数据时,是直接将数据拷贝到缓冲区或是从缓冲器拷贝数据,如果缓存区满了,溢出后就会丢失数据,因此合理的设置缓存区的大小很重要,注意发送缓冲区和接收缓冲区是两个缓存区,不是同一个。如下所示:
int BufSize = * ;
result = setsockopt(iSocketServer, SOL_SOCKET, SO_SNDBUF, (CHAR *)&BufSize, sizeof(BufSize));
if(result!= )
{
printf("Fail to set socket sendbuf options, errno = 0x%x!\n", result);
} int BufSize = * ;
result = setsockopt(iSocketServer, SOL_SOCKET, SO_RCVBUF, (CHAR *)&BufSize, sizeof(BufSize));
if(result != )
{
printf("Fail to set socket recvbuf options, errno = 0x%x!\n", result);
}
绑定socket
如果socket作为服务端,那么必须的操作是绑定一个IP,且绑定时并不是一定就会成功,因此使用多次绑定的方法,如下所示:
struct sockaddr_in6 ServerIp_V6 = {0x0};
memset(&ServerIp_V6, 0x0, sizeof(struct sockaddr_in6));
ServerIp_V6.sin6_family = AF_INET6;
ServerIp_V6.sin6_port = htons();
ServerIp_V6.sin6_addr = in6addr_any;
times = ;
while((result = bind(server, (struct sockaddr *)&ServerIp_V6, sizeof(struct sockaddr_in6))) != && times < 0x3)
{
times++;
printf("Bind socket faild %d times\n", times);
}
监听socket
同绑定socket的操作,注意最大监听个数的选择,如下所示:
times = ;
listenMax = 0x10;
while ((lResultCode = listen(server, listenMax)) != && times < 0x3)
{
times++;
printf("[tkQxPotnDaemon] listen socket faild %d times\n", times);
}
等待客户端连接
服务端一切设置好之后,就需要调用accpet阻塞式等待客户端来连接,如下所示:
struct sockaddr_in6 ManagerIp_v6 = {0x0};
int AddrLen = sizeof(struct sockaddr_in6);
while()
{
memset(&ManagerIp_v6, 0x0, sizeof(struct sockaddr_in6));
AcceptSocket = accept(server, (struct sockaddr *)&ManagerIp_v6, (socklen_t *)&AddrLen);
if (AcceptSocket < )
{
continue;
}
// 注意:ip是ManagerIp_v6.sin6_addr中的12、13、14、15位
// 如:ManagerIp_v6.sin6_addr[12]、ManagerIp_v6.sin6_addr[13]、ManagerIp_v6.sin6_addr[14]、ManagerIp_v6.sin6_addr[15]
// 注意:端口号是htons(ManagerIp_v6.sin6_port)
// 进行数据通信
}
服务端socket重用属性设置的更多相关文章
- tcp服务端socket
import socket if __name__ == '__main__': # 创建tcp服务端socket tcp_server_socket = socket.socket(socket.A ...
- socket模块实现基于UDP聊天模拟程序;socketserver模块实现服务端 socket客户端代码示例
socket模块 serSocket.setblocking(False) 设置为非阻塞: #coding=utf-8 from socket import * import time # 用来存储所 ...
- 在OneThink(ThinkPHP3.2.3)中整合阿里云OSS的PHP-SDK2.0.4,实现Web端直传,服务端签名直传并设置上传回调的实现流程
在OneThink(ThinkPHP3.2.3)中整合阿里云OSS的PHP-SDK2.0.4,实现本地文件上传流程 by shuijingwan · 2016/01/13 1.SDK安装 github ...
- Ali OSS服务端签名直传并设置上传回调
服务端签名直传并设置上传回调 背景 请参考 Web端直传实践 里的背景介绍. 当采用服务端签名后直传方案后,问题来了,用户上传数据后,很多场景下,应用服务器都要知道用户上传了哪些文件,文件名字,甚至如 ...
- Java多线程技术:实现多用户服务端Socket通信
目录 前言回顾 一.多用户服务器 二.使用线程池实现服务端多线程 1.单线程版本 2.多线程版本 三.多用户与服务端通信演示 四.多用户服务器完整代码 最后 前言回顾 在上一篇<Java多线程实 ...
- WCF服务端行为的一些设置
[ServiceBehavior( InstanceContextMode = InstanceContextMode.Single, //表示所有的请求都用一个服务实例来处理 Concurren ...
- ignite客户端找不到服务端的时候如何设置退出
ignite启动客户端时需要有服务端支持: Ignition.setClientMode(true); Ignition.start("ignite.xml"); 这里有个问题,当 ...
- JQuery ajax request及Java服务端乱码问题及设置
今天花了半天功夫才搞定2个乱码问题 1. 原先一直用form提交,现在改作JQuery ajax 提交,发现乱码. 2. window.location url中含有中文提交后,乱码. 第一个问题: ...
- c++ Socket客户端和服务端示例版本三(多线程版本)
客户端 #include <stdio.h> #include <stdlib.h> #include <errno.h> #include <sys/soc ...
随机推荐
- 一个非侵入的Go事务管理库——工作原理
在上一篇文章"一个非侵入的Go事务管理库--如何使用"中,我讲述了如何使用事务库.有些读者可能读过"清晰架构(Clean Architecture)的Go微服务: 事物管 ...
- v-model指令的学习(双向绑定)
v-bind 只能实现数据的单项绑定,从data到view,无法实现双向绑定 v-model可以实现表单元素和model中数据的双向绑定 注意:model只能运用到表单元素中 如:input sele ...
- 一文入门:XGBoost与手推二阶导
作者前言 在2020年还在整理XGB的算法,其实已经有点过时了..不过,主要是为了学习算法嘛.现在的大数据竞赛,XGB基本上已经全面被LGB模型取代了,这里主要是学习一下Boost算法.之前已经在其他 ...
- oracle 索引失效原因_汇总
1) 没有查询条件,或者查询条件没有建立索引 2) 在查询条件上没有使用引导列 3) 查询的数量是大表的大部分,应该是30%以上. 4) 索引本身失效 5) 查询条件使用函数在索引列上,或者对索引列进 ...
- android屏幕适配的全攻略--支持不同的屏幕尺寸适配平板和手机
一. 核心概念与单位详解 1. 什么是屏幕尺寸.屏幕分辨率.屏幕像素密度? 屏幕分辨率越大,手机越清晰 dpi就是dot per inch dot意思是点,就是每英寸上面的像素点数 android原始 ...
- 一条update SQL语句是如何执行的
一条更新语句的执行过程和查询语句类似,更新的流程涉及两个日志:redo log(重做日志)和binlog(归档日志).比如我们要将ID(主键)=2这一行的值加(c:字段)1,SQL语句如下: upda ...
- shell基本正则表达式
基本正则表达式 星号* 匹配它前面的字符串或正则表达式任意次(包括0次).比如,“1122*” 将匹配11+1个或多个2,其可能匹配的字符串将是112.1122.112222.11223343等 句点 ...
- Redis高级特性介绍以及实例分析
Redis基础类型回顾 转自:http://www.jianshu.com/p/af7043e6c8f9 String Redis中最基本,也是最简单的数据类型.注意,VALUE既可以是简单的Stri ...
- Spring Redis开启事务支持错误用法导致服务不可用
1.事故背景 在APP访问服务器接口时需要从redis中获取token进行校验,服务器上线后发现一开始可以正常访问,但只要短时间内请求量增长服务则无法响应 2.排查流程 (1)使用top指令查看C ...
- JavaScript基础CallBack函数(015)
前面提到,函数对象是可以作为参数传递给另一函数的,这时,作为参数的函数如果在内部被执行,那么它就是个回调函数(Callback): function writeCode(callback) { // ...