打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
标题: 实时SIGIO队列与sigwaitinfo的结合使用(提高socket服务能力)


这个是接收端也就是服务端的代码。
代码:
#define _GNU_SOURCE#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <fcntl.h>#include <errno.h>#include <string.h>#include <signal.h>#include <netinet/in.h>#include <arpa/inet.h>#include <sys/socket.h>#include <sys/types.h>#include <sys/ioctl.h>#define MAX_LENTH 1500#define SIG_FIFO_IO SIGRTMIN+1//这时SIGIO表示实时信号队列已满static char recv_buf[MAX_LENTH] = {0};int main(int argc, char *argv[]){int sockfd, on = 1;struct sigaction action;sigset_t newmask, oldmask;struct sockaddr_in addr;memset(&addr, 0, sizeof(addr));addr.sin_family = AF_INET;addr.sin_addr.s_addr = INADDR_ANY;addr.sin_port = htons(50001);if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {perror("Create socket failed");exit(-1);}if (bind(sockfd, (struct sockaddr *)&addr, sizeof(addr)) == -1) {perror("Bind socket failed");exit(-1);}/* memset(&action, 0, sizeof(action));action.sa_handler = sigio_handler;action.sa_flags = 0;sigaction(SIGIO, &action, NULL); */if (fcntl(sockfd, F_SETOWN, getpid()) == -1) {perror("Fcntl F_SETOWN failed");exit(-1);}if (fcntl(sockfd, F_SETSIG, SIG_FIFO_IO) == -1) {perror("Fcntl F_SETSIG failed");exit(-1);}if (ioctl(sockfd, FIOASYNC, &on) == -1) {perror("Ioctl FIOASYNC failed");exit(-1);}int rcvd_sig, len;siginfo_t info;sigemptyset(&newmask);sigaddset(&newmask, SIG_FIFO_IO);sigprocmask(SIG_BLOCK, &newmask, &oldmask);while (1) {rcvd_sig = sigwaitinfo(&newmask, &info);//siginfo中的_sigpool{si_band, si_fd},其中si_fd为socket的文件描述符值if (rcvd_sig == -1) {perror("sigio: sigwaitinfo");exit(-1);}else {printf("Signal %d, socket fd %d received from socket\n",rcvd_sig, info.si_fd);len = recv(sockfd, recv_buf, MAX_LENTH, MSG_DONTWAIT);if( len>0)puts( recv_buf);exit(-1);}}}
效率应该比较高,通过siginfo_t的si_fd可以找到相应的socket文件描述符,所以对多个客户端的连接也能处理,如果还配以使用si_band还能知道该信号具体的含义如下:
POLL_IN Data input available.
POLL_OUT Output buffers available.
POLL_MSG Input message available.
POLL_ERR I/O error.
POLL_PRI High priority input available.
POLL_HUP Device disconnected.
这些东西很像poll系统调用中struct pollfd中的revents。

发送端的代码跟我以前写的这个系列的一样,抄在下方。
代码:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <netinet/in.h> /*socket address struct*/
#include <arpa/inet.h> /*host to network convertion*/
#include <sys/socket.h>
#include <signal.h>
#define MAX_TRANSPORT_LENTH 512

int main()
{
struct sockaddr_in addr;
memset(&addr,0,sizeof(addr));
addr.sin_family =  AF_INET;
addr.sin_addr.s_addr = inet_addr("127.0.0.1");
addr.sin_port = htons(50001);

int sock;
sock = socket(AF_INET,SOCK_DGRAM,0);
if(sock == -1)
{
perror("Create socket failed");
exit(-1);
}

int ret;
ret = connect(sock,(struct sockaddr *)&addr,sizeof(addr));
if(ret == -1)
{
perror("Connect socket failed");
exit(-1);
}
while(1)
{
printf("Will send messge to server\n");
write(sock,"Some unknown infomation\n",MAX_TRANSPORT_LENTH);
sleep(1);
}

}
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
Linux网络编程一步一步学-UDP方式点对点通讯
unix domain socket示例一(SOCK
3个学习Socket编程的简单例子:TCP Server/Client, Select
Linux下getsockopt/setsockopt 函数说明 - xioahw的专栏 ...
socket网络编程快速上手(二)——细节问题(5)(完结篇)
14、socket编程实现回声客户端
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服