服务器程序:

#include <sys/wait.h>
#include <string.h>
#include <string.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <signal.h>
#include <arpa/inet.h>
#include <sys/select.h>
#include <sys/time.h>
#include <unistd.h>
#define SERV_PORT 3334
#define LISTENQ 5
#define MAXLINE 100 void str_echo(int sockfd)
{
ssize_t n;
char buf[MAXLINE]; again:
while ( (n = read(sockfd, buf, MAXLINE)) > 0)
write(sockfd, buf, n); if (n < 0 && errno == EINTR)
goto again;
else if (n < 0)
perror("read");
} void sig_chld(int signo)
{
pid_t pid;
int stat; while ( (pid = waitpid(-1, &stat, WNOHANG)) > 0)
printf("child %d terminated\n", pid);
return;
}
int main(int argc, char **argv)
{
int listenfd, connfd, udpfd, nready, maxfdp1;
char mesg[MAXLINE];
pid_t childpid;
fd_set rset;
ssize_t n;
socklen_t len;
const int on = 1;
struct sockaddr_in cliaddr, servaddr;
void sig_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, (struct sockaddr *) &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, (struct sockaddr *) &servaddr, sizeof(servaddr));
signal(SIGCHLD, sig_chld); /* must call waitpid() */ FD_ZERO(&rset);
maxfdp1 =( (listenfd>udpfd)?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() */
else
perror("select");
} if (FD_ISSET(listenfd, &rset)) {
len = sizeof(cliaddr);
connfd = accept(listenfd, (struct sockaddr *) &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, (struct sockaddr*) &cliaddr, &len); sendto(udpfd, mesg, n, 0, (struct sockaddr *) &cliaddr, len);
}
}
}

57-67    创建一个监听TCP套接字并捆绑服务器的众所周知的端口,设置SO_REUSEADDR套接字选项以防止该端口上已有连接存在。

70-77     还创建一个UDP套接字并捆绑与TCP套接字相同的端口。这里无需在调用bind之前设置SO_REUSEADDR套接字选项,因为TCP端口是独立于UDP端口的。

78        给SIGCHLD建立信号处理程序,因为TCP连接将由某个子进程处理。

83-90     我们调用select只是为了等待监听TCP套接字的可读条件或UDP套接字的可读条件。既然我们的sig_chld信号处理函数可能中断我们对select的调用,于是我们需要处理EINTR错误。

UNIX网络编程——使用select函数的TCP和UDP回射服务器程序的更多相关文章

  1. UNIX网络编程——使用select函数编写客户端和服务器

    首先看原先<UNIX网络编程--并发服务器(TCP)>的代码,服务器代码serv.c: #include<stdio.h> #include<sys/types.h> ...

  2. UNIX网络编程——UDP回射服务器程序(初级版本)以及漏洞分析

    该函数提供的是一个迭代服务器,而不是像TCP服务器那样可以提供一个并发服务器.其中没有对fork的调用,因此单个服务器进程就得处理所有客户.一般来说,大多数TCP服务器是并发的,而大多数UDP服务器是 ...

  3. UNIX网络编程读书笔记:图解TCP端口号和并发服务器

               图1 TCP服务器在端口21上执行被动打开                                                          图2 客户对服务器的 ...

  4. 【Unix网络编程】chapter5TCP回射服务器程序

    chapter5  5.1 概述 5.2 TCP回射服务器程序:main函数 int main(int argc, char **argv) { int listenfd,connfd; pid_t ...

  5. 【UNIX网络编程(三)】TCP客户/server程序演示样例

    上一节给出了TCP网络编程的函数.这一节使用那些基本函数编写一个完毕的TCP客户/server程序演示样例. 该样例运行的过程例如以下: 1.客户从标准输入读入一行文本,并写给server. 2.se ...

  6. Linux下select的用法--实现一个简单的回射服务器程序

    1.先看man手册 SYNOPSIS       /* According to POSIX.1-2001 */       #include <sys/select.h>       / ...

  7. UNIX网络编程——epoll 系列函数简介、与select、poll 的区别

    前面博客<<UNIX环境高级编程--epoll函数使用详解>>有关于epoll函数的讲解. 一.epoll 系列函数简介 #include <sys/epoll.h> ...

  8. 《Unix网络编程》卷一(简介TCP/IP、基础套接字编程)

    通常说函数返回某个错误值,实际上是函数返回值为-1,而全局变量errno被置为指定的常值(即称函数返回这个错误值). exit终止进程,Unix在一个进程终止时总是关闭该进程所有打开的描述符. TCP ...

  9. UNIX网络编程读书笔记:基本TCP套接口编程

    编写一个完整的TCP客户和服务器程序所需要的基本套接口函数: 1.socket函数(客户端.服务器端都必须调用) 参数family指明协议族(family),该参数也往往被称为协议域(domain). ...

随机推荐

  1. hdu5634 BestCoder Round #73 (div.1)

    Rikka with Phi  Accepts: 5  Submissions: 66  Time Limit: 16000/8000 MS (Java/Others)  Memory Limit: ...

  2. [luoguP3729]曼哈顿计划EX

    来自FallDream的博客,未经允许,请勿转载,谢谢. 艾登拥有一个计算机网络,每一台计算机都至少有着Intel Xeon E50 v40 + 40路GTX10800Titan的恐怖配置,并由无线网 ...

  3. SpringCloud学习之soa基础

    一.soa简单介绍 1)面向服务的架构(SOA)是一个组件模型,它将应用程序的不同功能单元(称为服务)通过这些服务之间定义良好的接口和契约联系起来.SOA是解决复杂业务模块,提高扩展性,维护性,可伸缩 ...

  4. React 深入系列4:组件的生命周期

    文:徐超,<React进阶之路>作者 授权发布,转载请注明作者及出处 React 深入系列4:组件的生命周期 React 深入系列,深入讲解了React中的重点概念.特性和模式等,旨在帮助 ...

  5. (转)Ensemble2015安装

    1 IIS安装和windows系统配置 1.1 IIS安装 检查是否安装好了IIS,可在[管理工具]的[服务管理器]中查看,如下图所示表示安装了IIS.   确认IIS已完全安装,点击上图中的Web服 ...

  6. js打印小结

    <script type="text/javascript"> //打印必备参数 var hkey_root,hkey_path,hkey_key; hkey_root ...

  7. RestTemplate的异常:Not enough variables available to expand

    原因:RestTemplate使用出错,我的情况是不知道这里要求用RestTemplate的使用格式,应该很多人都是这样吧?不过,看了下RestTemplate,感觉其实还是很好用的. RestTem ...

  8. 用background-image做成条纹背景

    效果: 实现: //html <div class="container"> <span class="tip span-1">1111 ...

  9. Day 2 Python数值计算

    一.数值数据类型 在Python中,数值数据类型有以下两种: 整数 整数用"int"数据类型表示.int类型的数据可以是正数也可以是负数,Python可以处理任意大小的整数. 浮点 ...

  10. ScalaPB(1): using protobuf in akka

    任何类型的实例作为消息在两端独立系统的机器之间进行传递时必须经过序列化/反序列化serialize/deserialize处理过程.假设以下场景:在一个网络里有两台连接的服务器,它们分别部署了独立的a ...