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.一台客户机从其标准输入(键盘)读入一行字符,并通过其套接 ...
随机推荐
- Java高级架构师(一)第41节:Nginx的配置优化以及使用建议
- php回溯
$sl = debug_backtrace(); 返回的$sl 是一个二维数组 包含如下元素: function string 当前的函数名,参见: __FUNCTION__. line intege ...
- 【原创】Eclipse中Android项目引用
1.选择名为SMSSDK的项目,右键--->Properties--->Android--->将Is Library勾上--->OK. 2.选中另一个名为FragmentDem ...
- Educational Codeforces Round 10 C. Foe Pairs 水题
C. Foe Pairs 题目连接: http://www.codeforces.com/contest/652/problem/C Description You are given a permu ...
- Pandas中Series和DataFrame的索引
在对Series对象和DataFrame对象进行索引的时候要明确这么一个概念:是使用下标进行索引,还是使用关键字进行索引.比如list进行索引的时候使用的是下标,而dict索引的时候使用的是关键字. ...
- Matlab 曲线绘制之线型和颜色 示例
估计很多人会碰到,当绘制的曲线特别多的时候,需要用不同的颜色和线型区分开这些曲线.根据STC论文,自己整理了一个颜色和线型的例子,供大家直接使用,直接引用PlotStyle这个数据结构就可以了. 示例 ...
- mOByDiC E90C2600 EOBD/OBDII to RS232 gateway
http://www.ozenelektronik.com/downs/pdf/oe90c2600.pdf Features • Compatible with EOBD/OBDII standard ...
- javascript比较两个时间大小
//var yourtime=document.getElementById('begin_time').value; var yourtime='2010-12-10 11:12'; yourtim ...
- 《.NET最佳实践》
<.NET最佳实践> 基本信息 原书名:Pro .NET Best Practices 原出版社: Apress 作者: (美)Stephen Ritchie 译者: 黄灯桥 黄浩宇 李永 ...
- Eclipse中在android项目中出现新建一个Activity后,出现整个project的报错以及包导入以后无法执行等等情况分析。
今天用Eclipse去写android项目,然后后面须要建一个Blank Activity后,非常正常的建立的.然后那个Activity是基于ActionBarAtivity,要导入v7,结果由于这 ...