|
这个是接收端也就是服务端的代码。- #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);
- }
-
- }
复制代码
以上代码版权属于realtang,您可以在GPLv3授权下使用。 |
|