udp套接字使用信号驱动式I/O
信号驱动式I/O的本质就是:进程预先告知内核当某个描写叙述符发生事件时,内核会向该进程发送SIGIO信号通知进程,进程可在信号处理函数中进行处理
进程能够通过fcntl打开O_ASYNC标志或ioctl打开FIOASYNC标志来通知内核,二者的差别是一些系统不支持fcntl,所以应尽量使用ioctl
对于TCP套接字产生SIGIO信号的条件:
1.监听套接字上有新连接请求完毕
2.某个断连请求发起
3.某个断连请求完毕
4.数据到达套接字
5.数据已从套接字发送走(输出缓冲区有空暇空间)
6.发生某个异步错误
对于UDP套接字产生SIGIO信号的条件:
1.数据报到达套接字
2.套接字上发生异步错误
对于套接字而言:TCP套接字和UDP套接字致使内核产生SIGIO信号的条件有所不同,当中TCP可产生该信号的条件较多,而UDP套接字产生该信号的条件仅仅有两个,由于我们无法得知详细是什么事件导致内核产生该信号。
。对于UDP套接字产生该信号条件的推断就简单的多。这也是信号驱动式I/O主要用于UDP套接字的原因。
套接字使用信号驱动式I/O的步骤:
1.建立SIGIO信号处理函数
2.设置设置套接字属主(使用fcntl的F_SETOWN命令)
3.开启信号驱动式I/O(fcntl打开O_ASYNC 或 ioctl打开FIOASYNC)
实例:
客户每隔1秒钟将系统时间发送到server,server通过SIGIO信号处理函数中接收数据
net.h
#ifndef MY_NET_H
#define MY_NET_H #include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <stdlib.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <time.h>
#include <string.h>
#include <sys/select.h>
#include <sys/time.h>
#include <errno.h>
#include <signal.h>
#include <iostream>
#include <sys/stat.h>
#include <fcntl.h>
#include <net/if.h>
#include <net/if_arp.h>
#include <sys/ioctl.h>
#include <sys/ioctl.h> using namespace std; char recvBuf[1025];
int listenfd; static void sigio_handler(int signo)
{
if (signo != SIGIO)
return; int ret;
while (1)
{
ret = recvfrom(listenfd, recvBuf, sizeof(recvBuf),
0, NULL, NULL);
if (ret < 0)
{
if (errno == EWOULDBLOCK)
break; perror("recvfrom error");
exit(-1);
} cout << recvBuf << endl;
}
} void init(int skfd)
{
int ret; //1.建立SIGIO信号的处理函数
signal(SIGIO, sigio_handler); //2.设置该套接字的属主
ret = fcntl(skfd, F_SETOWN, getpid());
if (ret < 0)
{
perror("fcntl error");
exit(-1);
} //3.开启该套接字的信号驱动式I/O
int on = 1;
ret = ioctl(skfd, FIOASYNC, &on);
if (ret < 0)
{
perror("ioctl error");
exit(-1);
}
} int prepare()
{
int skfd = socket(AF_INET, SOCK_DGRAM, 0);
if (skfd < 0)
return -1; struct sockaddr_in saddr;
bzero(&saddr, sizeof(saddr));
saddr.sin_family = AF_INET;
saddr.sin_port = htons(9999);
saddr.sin_addr.s_addr = htonl(INADDR_ANY); if (bind(skfd, (struct sockaddr*)&saddr, sizeof(saddr)) < 0)
return -1; return skfd;
} #endif
客户:
#include "net.h" int main()
{
int skfd;
skfd = socket(AF_INET, SOCK_DGRAM, 0);
if (skfd < 0)
{
perror("socket error");
exit(-1);
} int ret;
time_t tm;
struct sockaddr_in desAddr;
bzero(&desAddr, sizeof(desAddr));
desAddr.sin_family = AF_INET;
desAddr.sin_port = htons(9999);
desAddr.sin_addr.s_addr = inet_addr("127.0.0.1"); while (1)
{
time(&tm);
ret = sendto(skfd, ctime(&tm), strlen(ctime(&tm)), 0,
(struct sockaddr*)&desAddr, sizeof(desAddr));
if (ret < 0)
{
perror("");
exit(-1);
}
sleep(1);
} return 0;
}
server:
#include "net.h" int main()
{
listenfd = prepare();
if (listenfd < 0)
{
perror("prepare error");
exit(-1);
} init(listenfd);
while(1); return 0;
}
udp套接字使用信号驱动式I/O的更多相关文章
- UNIX网络编程——信号驱动式I/O
信号驱动式I/O是指进程预先告知内核,使得当某个描述符上发生某事时,内核使用信号通知相关进程. 针对一个套接字使用信号驱动式I/O,要求进程执行以下3个步骤: 建立SIGIO信号的信号处理函数. 设置 ...
- UNP学习笔记(第二十五章 信号驱动式I/O)
信号驱动式I/O是指进程预先告知内核,使得当某个描述符发生某事时,内核使用信号通知相关进程. 套接字的信号驱动式I/O 针对一个套接字使用信号驱动式I/O(SIGIO)要求进程执行以下3个步骤: 1. ...
- 信号驱动式I/O
信号驱动式I/O是指进程预先告知内核,使得当某个描述符上发生某事时,内核使用信号通知相关进程. 异步I/O是进程执行I/O系统调用(读或写)告知内核启动某个I/O操作,内核启动I/O操作后立刻返回到进 ...
- 计算机网络实验 UDP套接字编程
这是个傻瓜式操作教程 西科大计算机网络实验 UDP套接字编程 我用自己的Ubuntu16.04来举例,实验室的是虚拟机,差不多 只针对第三个题目,修改服务器来通过响应客户端发送的GetTime并发送给 ...
- Python之路(第三十二篇) 网络编程:udp套接字、简单文件传输
一.UDP套接字 服务端 # udp是无链接的,先启动哪一端都不会报错 # udp没有链接,与tcp相比没有链接循环,只有通讯循环 server = socket.socket(socket.AF_I ...
- QT下UDP套接字通信——QUdpSocket 简单使用
QT下UDP套接字通信--QUdpSocket QUdpSocket类提供一个UDP套接字. UDP(用户数据报协议)是一种轻量级.不可靠.面向数据报.无连接的协议.它可以在可靠性不重要的情况下使用. ...
- 《Unix 网络编程》08:基本UDP套接字编程
基本UDP套接字编程 系列文章导航:<Unix 网络编程>笔记 UDP 概述 流程图 recvfrom 和 sendto #include <sys/socket.h> ssi ...
- 探索UDP套接字编程
UDP和TCP处于同一层网络模型中,也就是运输层,基于二者之上的应用有很多,常见的基于TCP的有HTTP.Telnet等,基于UDP有DNS.NFS.SNMP等.UDP是无连接,不可靠的数据协议服务, ...
- 【Python网络编程】利用Python进行TCP、UDP套接字编程
之前实现了Java版本的TCP和UDP套接字编程的例子,于是决定结合Python的学习做一个Python版本的套接字编程实验. 流程如下: 1.一台客户机从其标准输入(键盘)读入一行字符,并通过其套接 ...
随机推荐
- [转] Eclipse的Tomcat插件安装
Eclipse的Tomcat服务器插件tomcatPlugin是由Sysdeo公司开发的,其下载地址是:http://www.eclipsetotale.com/tomcatPlugin.html ...
- CAS3.5.x(x>1)支持OAuth2 server
国内私募机构九鼎控股打造APP,来就送 20元现金领取地址:http://jdb.jiudingcapital.com/phone.html内部邀请码:C8E245J (不写邀请码,没有现金送)国内私 ...
- 【JSP EL】EL表达式里日期按照格式显示
转:http://blog.csdn.net/kaishuaige/article/details/8505174 JSP页面用EL表达式 输出date格式 1.头上引入标签 <%@ t ...
- python笔记16-执行cmd指令(os.system和os.popen)
os.system 1.如果想在cmd执行python脚本,可以直接用如下指令 python [xx.py绝对路径] 比如我写了个hello.py的脚本,在脚本里面写入内容:print("h ...
- 制作Java安装程序
这个工具利用 ANT 来制作在 Windows, MacOS X, Unix 平台上可执行的文件,比如 exe,zip,jar.ROXES ANT Tasks 基于 GPL 发布. http://ww ...
- [Android 新特性] 15项大改进 Android 4.4新特性解析
腾讯数码讯(编译:刘沙) 终于,Android系统迎来了久违的重大更新——Android 4.4 KitKat,并与新旗舰Nexus 5同时问世.那么,新的系统究竟都有怎样的改进.是否值得升级呢,下面 ...
- 查找链表中倒数第k个结点
题目:输入一个单向链表,输出该链表中倒数第k个结点.链表的倒数第0个结点为链表的尾指针.链表结点定义如下: struct ListNode { int m_nKey; ListNode* m_pNex ...
- Android宝典入门篇-进阶
学习Android前后有快有1个月了,本着不耍流氓,谈恋爱就要结婚的信念(其实AD开发也挺有趣的),做了自己的第一个Android小应用.本来准备今天和大家分享的,考虑到在不同屏幕上的效果没测试和本着 ...
- 最新office2003密钥
Microsoft Office Professional Edition 2003GWH28-DGCMP-P6RC4-6J4MT-3HFDY Office2003序列号注册码sn: WFDWY-XQ ...
- 加解密 3DES AES RSA 简介 示例 MD
Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...