#相关代码, [四号程序员] http://www.coder4.com
/*
* main.cc
*
* Created on: 2009-11-30
* Author: liheyuan
* Describe: 非阻塞模式服务器(Echo服务器)
*
* Last Date: 2009-11-30
* CopyRight: 2009 @ ICT LiHeyuan
*/
#include
using namespace std;
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define SERVER_PORT 18000
#define SERVER_QUEUE 10
#define FD_SET_SIZE 10
#define MAX_BUF 16
int main() {
//设置服务器Addr,在18000,任意IP监听
int serverFd;
serverFd = socket(AF_INET, SOCK_STREAM, 0);
/* 设置 serverFd 为非阻塞方式 */
int opt = SO_REUSEADDR;
setsockopt(serverFd, SOL_SOCKET, opt, &opt, sizeof(opt));
struct sockaddr_in serverAddr;
socklen_t serverAddrLen = sizeof(sockaddr_in);
serverAddr.sin_addr.s_addr = htonl(INADDR_ANY);
serverAddr.sin_port = htons(SERVER_PORT);
//绑定
if (bind(serverFd, (sockaddr*) &serverAddr, serverAddrLen)) {
cout << "Binding on " << SERVER_PORT << " fail." << endl;
return -1;
}
//创建等待队列
listen(serverFd, SERVER_QUEUE);
//设定fd_set
fd_set readfds, testfds;
FD_ZERO(&readfds);
FD_SET(serverFd,&readfds);
//非阻塞模式等待客户连接
struct sockaddr_in clientAddr;
int clientFd;
socklen_t clientAddrLen;
int len;
char buf[MAX_BUF];
while (1) {
FD_SET(serverFd,&readfds);
testfds = readfds;
//选择readfds中可用的fd
if (select(FD_SET_SIZE, &testfds, (fd_set *) NULL, (fd_set *) NULL,
(struct timeval *) NULL) > 0) {
if (FD_ISSET(serverFd,&testfds)) {
//如果服务器fd可用,则为accept
clientAddrLen = sizeof(sockaddr_in);
clientFd = accept(serverFd, (struct sockaddr*) &clientAddr,
&clientAddrLen);
if (clientFd == -1) {
cout << "accept() error" << endl;
return -1;
} else {
FD_SET(clientFd,&readfds);
cout << inet_ntoa(clientAddr.sin_addr) << " connect"
<< " at fd" << clientFd << endl;
}
}
//依次查询
for (int fd = 0; fd < FD_SET_SIZE; fd++) {
if (FD_ISSET(fd,&testfds)) {
//如果是Client活动,进行Echo
len = read(fd, buf, MAX_BUF);
if (len > 0) {
write(fd, buf, len);
} else {
//结束
cout << "Client end at" << clientFd << endl;
FD_CLR(fd,&readfds);
}
}
}
}
}
close(serverFd);
}