使用select函数的TCP和UDP回射服务器程序
来源:互联网 发布:sql select 多张表 编辑:程序博客网 时间:2024/05/29 12:14
服务器程序
/* include udpservselect01 */#include"unp.h"intmain(int argc, char **argv){intlistenfd, connfd, udpfd, nready, maxfdp1;charmesg[MAXLINE];pid_tchildpid;fd_setrset;ssize_tn;socklen_tlen;const inton = 1;struct sockaddr_incliaddr, servaddr;voidsig_chld(int);/* 4create listening TCP socket */listenfd = Socket(AF_INET, SOCK_STREAM, 0);bzero(&servaddr, sizeof(servaddr));servaddr.sin_family = AF_INET;servaddr.sin_addr.s_addr = htonl(INADDR_ANY);servaddr.sin_port = htons(SERV_PORT);Setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));Bind(listenfd, (SA *) &servaddr, sizeof(servaddr));Listen(listenfd, LISTENQ);/* 4create UDP socket */udpfd = Socket(AF_INET, SOCK_DGRAM, 0);bzero(&servaddr, sizeof(servaddr));servaddr.sin_family = AF_INET;servaddr.sin_addr.s_addr = htonl(INADDR_ANY);servaddr.sin_port = htons(SERV_PORT);Bind(udpfd, (SA *) &servaddr, sizeof(servaddr));/* end udpservselect01 *//* include udpservselect02 */Signal(SIGCHLD, sig_chld);/* must call waitpid() */FD_ZERO(&rset);maxfdp1 = max(listenfd, udpfd) + 1;for ( ; ; ) {FD_SET(listenfd, &rset);FD_SET(udpfd, &rset);if ( (nready = select(maxfdp1, &rset, NULL, NULL, NULL)) < 0) {if (errno == EINTR)continue;/* back to for() */elseerr_sys("select error");}if (FD_ISSET(listenfd, &rset)) {len = sizeof(cliaddr);connfd = Accept(listenfd, (SA *) &cliaddr, &len);if ( (childpid = Fork()) == 0) {/* child process */Close(listenfd);/* close listening socket */str_echo(connfd);/* process the request */exit(0);}Close(connfd);/* parent closes connected socket */}if (FD_ISSET(udpfd, &rset)) {len = sizeof(cliaddr);n = Recvfrom(udpfd, mesg, MAXLINE, 0, (SA *) &cliaddr, &len);Sendto(udpfd, mesg, n, 0, (SA *) &cliaddr, len);}}}/* end udpservselect02 */
创建TCP套接字
- 17~28 创建一个监听套接字并捆绑服务器到总所周知的端口,设置
SO_REUSEADDR
套接字选项防止该端口上已有连接存在。
创建UDP套接字
- 30~38 还创建了一个UDP套接字捆绑于TCP套接字相同的端口,设置
SO_REUSEADDR
套接字选项,因为TCP端口是独立于UDP端口的。
给SIGCHLD建立信号处理程序
- 42 因为TCP连接将由某个子程序处理。给出这个信号处理函数见下面。
准备调用select
- 44~45 我们给
select
初始化一个描述符集,并计算出我们等待的两个描述符的较大者。
调用select
- 47~54 我们调用select只是为了等待监听TCP套接字的可读条件或UDP套接字的可读条件。 既然我们的
sig_chld
信号处理函数可能中断我们对select
的调用,我们于是需要处理EINTR
错误。
处理新的客户端连接
- 56-66 当监听的TCP套接字可读时,我们
accept
一个新的客户连接,fork
一个子程序,并在子程序进程中调用str_echo
函数。
处理数据报的到达
- 68~74 如果UDP套接字可读,那么已有一个数据报到达。我们使用
recvfrom
读入它,再使用sendto
把它发回客户端。
客户端程序(tcp和udp)
TCP客户端程序
#include"unp.h"intmain(int argc, char **argv){intsockfd;struct sockaddr_inservaddr;if (argc != 2)err_quit("usage: tcpcli <IPaddress>");sockfd = Socket(AF_INET, SOCK_STREAM, 0);bzero(&servaddr, sizeof(servaddr));servaddr.sin_family = AF_INET;servaddr.sin_port = htons(SERV_PORT);Inet_pton(AF_INET, argv[1], &servaddr.sin_addr);Connect(sockfd, (SA *) &servaddr, sizeof(servaddr));str_cli(stdin, sockfd);/* do it all */exit(0);}
UDP客户端程序
#include"unp.h"intmain(int argc, char **argv){intsockfd;struct sockaddr_inservaddr;if (argc != 2)err_quit("usage: udpcli <IPaddress>");bzero(&servaddr, sizeof(servaddr));servaddr.sin_family = AF_INET;servaddr.sin_port = htons(SERV_PORT);Inet_pton(AF_INET, argv[1], &servaddr.sin_addr);sockfd = Socket(AF_INET, SOCK_DGRAM, 0);dg_cli(stdin, sockfd, (SA *) &servaddr, sizeof(servaddr));exit(0);}
信号处理程序
#include"unp.h"voidsig_chld(int signo){pid_tpid;intstat;while ( (pid = waitpid(-1, &stat, WNOHANG)) > 0)printf("child %d terminated\n", pid);return;}
UDP的回射服务器程序:dg_echo
函数
#include <unp.h>void dg_echo(int sockfd, SA *pcliaddr, socklen_t clilen){int n;socklen_tlen;char mesg[MAXLINE];for(;;){len = clilen;n = Recvfrom(sockfd, mesg, MAXLINE, 0, pcliaddr, &len);Sendto(sockfd, mesg, n, 0, pcliaddr, len);}}
UDP的回射客户程序:dg_cli
函数
#include <unp.h>void dg_cli(FILE *fp, int sockfd, const SA* pservaddr, socklen_t servlen){int n;charsendline[MAXLINE], recvline[MAXLINE+1];while(Fgets(sendline, MAXLINE, fp) != NULL){Sendto(sockfd, sendline, strlen(sendline), 0, pservaddr, servlen);n = Recvfrom(sockfd, recvline, MAXLINE, 0, NULL, NULL);recvline[n] = '\0';Fputs(recvline, stdout);}}
- UNIX网络编程——使用select函数的TCP和UDP回射服务器程序
- 使用select函数的TCP和UDP回射服务器程序
- 使用select函数的TCP和UDP回射服务器程序
- 网络编程学习笔记(使用select函数的TCP和UDP回射服务器程序)
- select函数在TCP和UDP回射服务器中的应用
- Linux下使用epoll函数同时处理TCP请求和UDP请求的回射服务器
- 《UNIX网络编程 卷1》 笔记: 使用select函数的单进程TCP回射服务器程序
- TCP & UDP服务器(select和fork)
- 同时使用tcp和udp回射服务器
- select写的UDP/TCP测试服务器
- 基于select函数的单进程并发服务器程序----TCP
- select函数的单进程和TCP回射服务器应用模型
- 《unix网络编程》(19)使用select的TCP和UDP回射程序
- UNIX网络编程学习(15)--使用单进程和select的TCP服务器程序
- 游戏服务器使用TCP和UDP
- I/O复用Select函数的UDP和TCP客户端和服务端
- tcp客户/服务器回射程序之四-----select函数的使用
- TCP和UDP服务器的设计
- sublime Text 3 的教程和一些网站
- 解决安装完Ubuntu系统后启动项中没有Ubuntu的问题
- ASCII码排序JAVA实现
- jQuery Ajax事件-ajaxSend(callback)
- 已经显现了出来的飞秋下载
- 使用select函数的TCP和UDP回射服务器程序
- 它们翻滚着的飞秋下载
- poj 1523 SPF
- 神奇的构造代码块
- 做为技术人员为什么要写博客
- Tutorial 14 - Camera Control - Part 1
- Android_ListView_Adapter使用和数据动态加载
- Python挑战的解决方案(1-10)
- 【白话经典算法系列之十七】 数组中只出现一次的数