socket信号驱动

为了使一个套接字能够使用信号驱动I/O,至少需要以下3步操作。

  • 1.安装SIGIO信号
  • 2.套接字的拥有者设定为当前进程。因为SIGIO信号只会送到socket拥有者进程. 通过fcntl的F_SETOWN
  • 3.套接字必须被允许使用异步I/O。 通过fcntl的F_SETFL,设置为O_ASYNC

在UDP通信中,下面情况会产生SIGIO信号

在TCP通信中,下面情况会产生SIGIO信号

例子:

下面的代码好奇怪,说是UDP的,但是发送接收用的是send, recv 而且客户端还跟服务器连接了;说是TCP,但是socket建立的时候用的是SOCK_DGRAM.

而且代码是可以跑通的。

服务器:

#include<stdio.h>
#include<stdlib.h>
#include<errno.h>
#include<string.h>
#include<sys/types.h>
#include<netinet/in.h>
#include<netinet/tcp.h>
#include<sys/socket.h>
#include<sys/wait.h>
#include<unistd.h>
#include<arpa/inet.h>
#include<sys/time.h>
#include<netdb.h>
#include<fcntl.h>
#include<signal.h>
#include<sys/ioctl.h>
#define MAX_LENTH 1500 //针对SIGIO信号处理
static int nqueue = ;
void sigio_handler(int signum)
{
if(signum == SIGIO)
nqueue++;
printf("signum = %d, nqueue = %d\n", signum, nqueue); //打印信号值
return;
}
static recv_buf[MAX_LENTH]; int main(int argc, char *argv[])
{
int sockfd, on = ;
struct sigaction action;
sigset_t newmask, oldmask;
struct sockaddr_in ser_addr;
if(argc != )
{
printf("use: %s ip_add port\n", argv[]);
exit(EXIT_FAILURE);
} memset(&ser_addr, , sizeof(ser_addr));
ser_addr.sin_family = AF_INET; //使用IPv4
ser_addr.sin_port = htons(atoi(argv[]));
if(inet_aton(argv[], (struct in_addr *)&ser_addr.sin_addr.s_addr) == )
{
perror(argv[]);
exit(EXIT_FAILURE);
}
//创建socket
if((sockfd = socket(AF_INET, SOCK_DGRAM, )) == -)
{
perror("socket");
exit(EXIT_FAILURE);
}
//绑定IP地址
if(bind(sockfd, (struct sockaddr *)&ser_addr, sizeof(ser_addr)) == -)
{
perror("bind");
exit(EXIT_FAILURE);
}
memset(&action, , sizeof(action));
action.sa_handler = sigio_handler;
action.sa_flags = ;
//安装信号
sigaction(SIGIO, &action, NULL);
//设置socket拥有者
if(fcntl(sockfd, F_SETOWN, getpid()) == -)
{
perror("fcntl F_SETOWN");
exit(EXIT_FAILURE);
}
//设置socket为信号驱动型
if(ioctl(sockfd, FIOASYNC, &on) == -)
{
perror("ioctl FIOASYNC");
exit(EXIT_FAILURE);
}
sigemptyset(&oldmask);
sigemptyset(&newmask);
sigaddset(&newmask, SIGIO);
printf("get ready\n");
while()
{
int len;
//设置当前阻塞的信号
sigprocmask(SIG_BLOCK, &newmask, &oldmask);
//等待信号
while(nqueue == )
sigsuspend(&oldmask);
memset(recv_buf, '\0', MAX_LENTH);
//非阻塞接收数据
len = recv(sockfd, recv_buf, MAX_LENTH, MSG_DONTWAIT);
if(len == - && errno == EAGAIN)
nqueue = ;
//修改进程阻塞的信号
sigprocmask(SIG_SETMASK, &oldmask, NULL);
if(len >= )
printf("recv %d byte, msg is %s\n", len, recv_buf);
} }

客户端

#include<stdio.h>
#include<stdlib.h>
#include<errno.h>
#include<string.h>
#include<sys/types.h>
#include<netinet/in.h>
#include<netinet/tcp.h>
#include<sys/socket.h>
#include<sys/wait.h>
#include<unistd.h>
#include<arpa/inet.h>
#include<sys/time.h>
#include<netdb.h>
#include<fcntl.h>
#include<signal.h>
#include<sys/ioctl.h>
#define MAX_LENTH 1500 int main(int argc, char *argv[])
{
struct sockaddr_in addr;
int sock_fd, ret;
char snd_buf[MAX_LENTH];
if(argc != ) //参数需要服务器的IP和端口
{
printf("use: %s ip_add port\n", argv[]);
exit(EXIT_FAILURE);
}
memset(&addr, , sizeof(addr));
addr.sin_family = AF_INET;
if(inet_aton(argv[], (struct in_addr *)&addr.sin_addr.s_addr) == )
{
perror(argv[]);
exit(EXIT_FAILURE);
}
addr.sin_port = htons(atoi(argv[]));
//创建socket
if((sock_fd = socket(AF_INET, SOCK_DGRAM, )) == -)
{
perror("socket");
exit(EXIT_FAILURE);
}
//向服务器发起连接 ??这不是TCP的么
if(ret = connect(sock_fd, (struct sockaddr *)&addr, sizeof(addr)) == -)
{
perror("connect");
exit(EXIT_FAILURE);
}
while()
{
printf("input msg to send:");
memset(snd_buf, '\0', MAX_LENTH);
fgets(snd_buf, MAX_LENTH - , stdin);
write(sock_fd, snd_buf, MAX_LENTH - );
}
}

【linux高级程序设计】(第十五章)UDP网络编程应用 4的更多相关文章

  1. 读书笔记 - js高级程序设计 - 第十五章 使用Canvas绘图

    读书笔记 - js高级程序设计 - 第十三章 事件   canvas 具备绘图能力的2D上下文 及文本API 很多浏览器对WebGL的3D上下文支持还不够好   有时候即使浏览器支持,操作系统如果缺缺 ...

  2. JavaScript高级程序设计:第五章

    引用类型 一.object类型: 创建object实例的方式有两种.第一种是使用new操作符后跟Object构造函数,如下所示: var  person = new  Object(): person ...

  3. 《javascript高级程序设计》第五章 reference types

    第5 章 引用类型5.1 Object 类型5.2 Array 类型 5.2.1 检测数组 5.2.2 转换方法 5.2.3 栈方法 5.2.4 队列方法 5.2.5 重排序方法 5.2.6 操作方法 ...

  4. 【linux高级程序设计】(第九章)进程间通信-管道 1

    Linux操作系统所支持的主要进程间的通信机制. 无名管道 PIPE cat test.txt| grep hello 上面这种管道,将一个命令的输出作为另一个命令的输入,而这种管道是临时的,命令执行 ...

  5. linux高级管理第十二章--rsync

    实验部分 1.安装rsync 2.配置文件 3.配置密码 4.后续 5.为了测试,创建几个文件 配置实时同步 1.调整inotify内核参数 安装inotify-tools 测试同步 编写脚本 验证 ...

  6. 《JAVASCRIPT高级程序设计》第五章(2)

    一.Date类型 Date类型类型用于保存日期,有以下几种创建方式: //获取当前时间 var now = new Date(); //获取当前时间的毫秒数 var nowSecond = Date. ...

  7. 《JAVASCRIPT高级程序设计》第五章(1)

    引用类型是一种将数据和功能组合到一起的数据结构,它与类相似,但是是不同的概念:ECMAScript虽然是一门面向对象的语言,但它不具备传统的面向对象语言所支持的类和结构等基本结构.引用类型也被称为“对 ...

  8. Javascript高级程序设计笔记 <第五章> 引用类型

    一.object类型 创建object实例的方式有两种: //第一种使用new操作符跟构造函数 var person= new Object(); person.name="小王" ...

  9. Javascript高级程序设计复习——第五章引用类型 【原创】

    5.1  Object类型 1:创建Object实例的两种方式 ①new构造法 var obj1 = new Object(); 注意大写!不传递参数时可以省略圆括号 obj1.hehe = &quo ...

  10. Linux高级运维 第五章 Vim编辑器和恢复ext4下误删除的文件-Xmanager工具

    5.1  vim主要模式介绍,vim命令模式. 确保系统已经安装了VIM工具 [root@panda ~]# rpm -qf `which vim` [root@panda ~]# rpm -qf ` ...

随机推荐

  1. linux centos7--linux和window共享文件(samba)

    这里以VMWARE与主控真机来做实现实现 由于SMB在centos中自带,所以,无需像网上说的样子,要这删除,那卸载,直接搜索是否存在SAMBA的安装文件 一 查询包是否存在 [root@localh ...

  2. laravel5.5用户认证源码分析

    目录 1. 生成相关文件和配置 2. 分析路由文件 3. 以登陆开始为例,分析auth到底是怎么工作的 3.1 分析登录文件 3.2 分析门面Auth. 1. 生成相关文件和配置 快速生成命令 php ...

  3. 【Binary Tree Right Side View 】cpp

    题目: Given a binary tree, imagine yourself standing on the right side of it, return the values of the ...

  4. 关于在虚拟机上安装iOS所遇到的问题

    先配一张成功的图片: 要想实现上图所示的,就要安装 unlocker206, 安装完unlocker206 不用改里面的内容!!!看到**经验上说还要改内容,结果我试了很多次,根本不行,其实问题不在改 ...

  5. Oracle 学习----游标(使用无参光标cursor)

    表: ----游标----------------------------- declare cursor tt is select name,sal from temp; vname temp.na ...

  6. Java访问修饰符(控制属性或方法在哪些范围内可见)

    default:不加控制符的时候,就是default,只能在本包内访问 public:公有的,在本类之外其他类中可以访问,不在本包内也可以访问 private:私有的,在本类之外其他类不能访问 pro ...

  7. html 网页注意事项

    html 知识总结; 1.内外边距 去掉浮动 *{ margin:0; padding:0; } 2.清除浮动 .clearfix:after { content:""; disp ...

  8. Java Web Action DAO Service层次理解

    参考来源:http://blog.csdn.net/inter_peng/article/details/41021727 1. Action/Service/DAO简介: Action是管理业务(S ...

  9. icon fonts generator & svg

    icon fonts generator https://icomoon.io/app/#/select https://icomoon.io/ http://fontastic.me/ http:/ ...

  10. KNN算法在保险业精准营销中的应用

    版权所有,可以转载,禁止修改.转载请注明作者以及原文链接. 一.KNN算法概述 KNN是Machine Learning领域一个简单又实用的算法,与之前讨论过的算法主要存在两点不同: 它是一种非参方法 ...