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

使用SIGURG信号接受带外数据

这是一个服务器程序,使用SIGURG信号接受带外数据。

#include<sys/socket.h>
#include<sys/types.h>
#include<arpa/inet.h>
#include<netinet/in.h>
#include<assert.h>
#include<unistd.h>
#include<signal.h>
#include<stdio.h>
#include<errno.h>
#include<string.h>
#include<fcntl.h>
#include<stdlib.h>

#define BUF_SIZE 1024

static int connfd;

/* SIGURG 信号的处理函数 */
void sig_urg(int sig)
{
	int save_errno = errno;
	char buffer[BUF_SIZE];
	memset(buffer, '\0', BUF_SIZE);
	int ret = recv(connfd, buffer, BUF_SIZE - 1, MSG_OOB);	/* 接收带外数据 */
	printf("got %d bytes of oob data '%s'\n", ret, buffer);
	errno = save_errno;
}

void addsig(int sig, void (*sig_handler)(int))
{
	struct sigaction sa;
	memset(&sa, '\0', sizeof(sa));
	sa.sa_handler = sig_handler;
	sa.sa_flags |= SA_RESTART;
	sigfillset(&sa.sa_mask);
	assert(sigaction(sig, &sa, NULL) != -1);
}

int main(int argc, char* argv[])
{
	if (argc <= 2)
	{
		return 1;
	}
	const char* ip = argv[1];
	int port = atoi(argv[2]);

	struct sockaddr_in address;
	bzero(&address, sizeof(address));
	address.sin_family = AF_INET;
	address.sin_port = htons(port);
	inet_pton(AF_INET, ip, &address.sin_addr);

	int sockfd = socket(PF_INET, SOCK_STREAM, 0);
	assert(sockfd >= 0);

	int ret = bind(sockfd, (struct sockaddr*)&address, sizeof(address));
	assert(ret != -1);

	ret = listen(sockfd, 5);
	assert(ret != -1);

	struct sockaddr_in client;
	socklen_t client_addrlen = sizeof(client);
	connfd = accept(sockfd, (struct sockaddr*)&client, &client_addrlen);
	if (connfd < 0)
	{
		printf("errno is: %d\n", errno);
	}
	else
	{
		addsig(SIGURG, sig_urg);
		/* 使用 SIGURG 信号之前,必须设置 socket 的宿主进程或进程组为当前进程,意思是:当该 socket 上有带外数据时,将 SIGURG 发送给那个进程或进程组 */
		fcntl(connfd, F_SETOWN, getpid());

		char buffer[BUF_SIZE];
		while (1)	/* 循环接受普通数据 */
		{
			memset(buffer, '\0', BUF_SIZE);
			ret = recv(connfd, buffer, BUF_SIZE - 1, 0);
			if (ret <= 0)
			{
				break;
			}
			printf("got %d bytes of normal data '%s'\n", ret, buffer);
		}
		close(connfd);
	}

	close(sockfd);
	return 0;
}

F_SETOWN专门用于设定SIGIOSIGURG信号的宿主进程的PID或者进程组的组ID。

相关文章:

  • 信号 ——《Linux高性能服务器编程》第10章——读书笔记
  • Linux 文件I/O 及其 多个相关函数
  • python——学校课程预习+复习
  • Linux 进程———详解
  • Linux服务器实例程序———使用定时器列表处理非活动连接
  • 各种最短路问题的常用算法模板
  • Linux高级进程编程———在任意两个进程间传递文件描述符:使用 sendmsg 和 recvmsg 实现
  • Linux 线程———详解
  • Linux 中与字符串相关的函数strpbrk、strcasecmp、strspn(不间断更新)
  • C++ printf族函数
  • 最小生成树的常用算法模板
  • 一个服务器压力测试程序
  • 图论——二分图
  • 面向对象程序设计———组合、委托 与 继承
  • C++设计模式
  • Google 是如何开发 Web 框架的
  • 【每日笔记】【Go学习笔记】2019-01-10 codis proxy处理流程
  • CentOS7 安装JDK
  • Django 博客开发教程 16 - 统计文章阅读量
  • Linux快速配置 VIM 实现语法高亮 补全 缩进等功能
  • passportjs 源码分析
  • PHP 小技巧
  • Redis字符串类型内部编码剖析
  • SegmentFault 社区上线小程序开发频道,助力小程序开发者生态
  • vue2.0项目引入element-ui
  • 多线程事务回滚
  • 发布国内首个无服务器容器服务,运维效率从未如此高效
  • 前端每日实战:70# 视频演示如何用纯 CSS 创作一只徘徊的果冻怪兽
  • 前端之React实战:创建跨平台的项目架构
  • 如何利用MongoDB打造TOP榜小程序
  • 我建了一个叫Hello World的项目
  • 智能网联汽车信息安全
  • 看到一个关于网页设计的文章分享过来!大家看看!
  • FaaS 的简单实践
  • ​人工智能之父图灵诞辰纪念日,一起来看最受读者欢迎的AI技术好书
  • #include
  • #Linux(make工具和makefile文件以及makefile语法)
  • #我与Java虚拟机的故事#连载10: 如何在阿里、腾讯、百度、及字节跳动等公司面试中脱颖而出...
  • (10)工业界推荐系统-小红书推荐场景及内部实践【排序模型的特征】
  • (2009.11版)《网络管理员考试 考前冲刺预测卷及考点解析》复习重点
  • (4)事件处理——(2)在页面加载的时候执行任务(Performing tasks on page load)...
  • (4)通过调用hadoop的java api实现本地文件上传到hadoop文件系统上
  • (未解决)jmeter报错之“请在微信客户端打开链接”
  • (转)jQuery 基础
  • (转)socket Aio demo
  • (转)我也是一只IT小小鸟
  • (转载)虚函数剖析
  • .Net 8.0 新的变化
  • .NET/C# 的字符串暂存池
  • .NET/C# 使用反射调用含 ref 或 out 参数的方法
  • .NET构架之我见
  • .sdf和.msp文件读取
  • [AutoSar]BSW_OS 02 Autosar OS_STACK
  • [c]扫雷
  • [C++随笔录] 红黑树