当前位置: 技术问答>linux和unix
关于select系统调用的一道题
来源: 互联网 发布时间:2016-09-11
本文导语: 有这么一道题: 编写:将从命令提示符处输入的字符串用TCP的方式送信到echo服务器,接受从服务器返回来的响应,并表示出来的客户端程序。 tcp-echoc 如下: $ ./tcp-echoc Usage: tcp-echoc dsthost dstport ./echoc 127.0.0.1 7 se...
有这么一道题:
编写:将从命令提示符处输入的字符串用TCP的方式送信到echo服务器,接受从服务器返回来的响应,并表示出来的客户端程序。 tcp-echoc
如下:
$ ./tcp-echoc
Usage: tcp-echoc dsthost dstport
./echoc 127.0.0.1 7
sendmsg> Hello!, this is test message
recvmsg> Hello!, this is test message
echo服务器:通过TCP/IP的端口号7来提供服务
下面是服务器端的代码(IPv4和IPv6地址都适用的):
#include
#include
#include
#include
#include
#include
#include
#include
#define SERVPORT 5000 /*服务器监听端口号 */
#define BACKLOG 10 /* 最大同时连接请求数 */
#define BUFF_SIZE 1024
void main()
{
int sockfd,client_fd; /*sock_fd:监听socket;client_fd:数据传输socket */
struct sockaddr_in6 my_addr; /* 本机地址信息 */
struct sockaddr_in6 remote_addr; /* 客户端地址信息 */
if ((sockfd = socket(AF_INET6, SOCK_STREAM, 0)) == -1)
{
perror("socket创建出错!"); exit(1);
}
bzero(&my_addr, sizeof(my_addr));
my_addr.sin6_family=AF_INET6;
my_addr.sin6_port=htons(SERVPORT);
my_addr.sin6_addr = in6addr_any;
if (bind(sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr_in6)) == -1)
{
perror("bind出错!");
exit(1);
}
if (listen(sockfd, BACKLOG) == -1) {
perror("listen出错!");
exit(1);
}
while(1) {
int sin_size = sizeof(struct sockaddr_in); //sockaddr_in6
char temp[INET6_ADDRSTRLEN];
if ((client_fd = accept(sockfd, (struct sockaddr *)&remote_addr, &sin_size)) == -1) {
perror("accept出错");
continue;
}
printf("received a connection from %sn", inet_ntop(AF_INET6, remote_addr.sin6_addr, temp, sizeof(temp)));
if (!fork()) { /* 子进程代码段 */
char buffer[BUFF_SIZE];
int len = recv(client_fd, buffer, BUFF_SIZE, 0);
while(len > 0)
{
if (send(client_fd, buffer, len, 0) == -1)
{
perror("unable to send!");
close(client_fd);
exit(1);
}
len = recv(client_fd, buffer, BUFF_SIZE, 0);
}
close(client_fd);
exit(0);
}
close(client_fd);
}
}
请把上面程序改为下面形式,并且利用select(),poll()等系统调用,实现I/O复用,满足多客户端的程序 multi-tcp-echos
如下:
$ ./multi-tcp-echos
Usage: multi-tcp-echos port
./multi-tcp-echos 5000
原客户端的程序见 http://zhidao.baidu.com/question/164851602.html
编写:将从命令提示符处输入的字符串用TCP的方式送信到echo服务器,接受从服务器返回来的响应,并表示出来的客户端程序。 tcp-echoc
如下:
$ ./tcp-echoc
Usage: tcp-echoc dsthost dstport
./echoc 127.0.0.1 7
sendmsg> Hello!, this is test message
recvmsg> Hello!, this is test message
echo服务器:通过TCP/IP的端口号7来提供服务
下面是服务器端的代码(IPv4和IPv6地址都适用的):
#include
#include
#include
#include
#include
#include
#include
#include
#define SERVPORT 5000 /*服务器监听端口号 */
#define BACKLOG 10 /* 最大同时连接请求数 */
#define BUFF_SIZE 1024
void main()
{
int sockfd,client_fd; /*sock_fd:监听socket;client_fd:数据传输socket */
struct sockaddr_in6 my_addr; /* 本机地址信息 */
struct sockaddr_in6 remote_addr; /* 客户端地址信息 */
if ((sockfd = socket(AF_INET6, SOCK_STREAM, 0)) == -1)
{
perror("socket创建出错!"); exit(1);
}
bzero(&my_addr, sizeof(my_addr));
my_addr.sin6_family=AF_INET6;
my_addr.sin6_port=htons(SERVPORT);
my_addr.sin6_addr = in6addr_any;
if (bind(sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr_in6)) == -1)
{
perror("bind出错!");
exit(1);
}
if (listen(sockfd, BACKLOG) == -1) {
perror("listen出错!");
exit(1);
}
while(1) {
int sin_size = sizeof(struct sockaddr_in); //sockaddr_in6
char temp[INET6_ADDRSTRLEN];
if ((client_fd = accept(sockfd, (struct sockaddr *)&remote_addr, &sin_size)) == -1) {
perror("accept出错");
continue;
}
printf("received a connection from %sn", inet_ntop(AF_INET6, remote_addr.sin6_addr, temp, sizeof(temp)));
if (!fork()) { /* 子进程代码段 */
char buffer[BUFF_SIZE];
int len = recv(client_fd, buffer, BUFF_SIZE, 0);
while(len > 0)
{
if (send(client_fd, buffer, len, 0) == -1)
{
perror("unable to send!");
close(client_fd);
exit(1);
}
len = recv(client_fd, buffer, BUFF_SIZE, 0);
}
close(client_fd);
exit(0);
}
close(client_fd);
}
}
请把上面程序改为下面形式,并且利用select(),poll()等系统调用,实现I/O复用,满足多客户端的程序 multi-tcp-echos
如下:
$ ./multi-tcp-echos
Usage: multi-tcp-echos port
./multi-tcp-echos 5000
原客户端的程序见 http://zhidao.baidu.com/question/164851602.html
|
《UNIX网络编程》第6章,IO多路复用