Linux 网络编程(多路复用)

时间:2023-03-09 08:50:15
Linux 网络编程(多路复用)
  • 服务器端代码
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/socket.h>
#include<sys/types.h>
#include<unistd.h>
#include<netinet/in.h>
#include <errno.h>
#include <sys/fcntl.h> typedef struct _CLIENT{
int fd;
struct sockaddr_in addr;
char recvbuf[];
}CLIENT_S; int main(int argc, char** argv){ int socketfd,new_fd;
CLIENT_S sock_list[];
struct sockaddr_in server_addr;
struct sockaddr_in client_addr;
struct timeval tv;
char recvbuf[];
int res;
int max;
int len,nbytes;
int port = ;
int i; for(i = ; i < ; i ++){
sock_list[i].fd = -;
} if((socketfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == ){
fprintf(stderr, "socket Error:%s\n\a", strerror(errno));
exit();
} //设置为非阻塞
if (fcntl(socketfd, F_SETFL, O_NONBLOCK) == -) {
fprintf(stderr, "fcntl Error:%s\n\a", strerror(errno));
exit();
} bzero(&server_addr, sizeof(struct sockaddr_in));
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(port);
server_addr.sin_addr.s_addr = htonl(INADDR_ANY); if((bind(socketfd, &server_addr, sizeof(server_addr))) == -){
fprintf(stderr, "bind Error:%s\n\a", strerror(errno));
exit();
} if(listen(socketfd, ) == -){
fprintf(stderr, "listen Error:%s\n\a", strerror(errno));
exit();
} sock_list[].fd = socketfd;
max = socketfd;
fd_set watchset;//select所需要的文件描述符
FD_ZERO(&watchset);
//将监听socket放入扫描集合
FD_SET(socketfd, &watchset); while(){
FD_ZERO(&watchset); FD_SET(socketfd, &watchset);
for(i = ; i < ; i ++){
if (sock_list[i].fd != -) {
FD_SET(sock_list[i].fd, &watchset);
}
} res = select(max + , &watchset, NULL, NULL, NULL); if(- == res){
fprintf(stderr, "select Error:%s\n\a", strerror(errno));
exit();
}else if( == res){
printf("Select() break and the return num is");
continue;
}else{
if(FD_ISSET(socketfd, &watchset)){
len = sizeof(struct sockaddr_in);
if ((new_fd = accept(socketfd,
(struct sockaddr *)&client_addr,
&len)) == -) {
fprintf(stderr, "Accept error:%s\n\a", strerror(errno));
exit();
} for(i = ; i < ; i ++){
if (sock_list[i].fd == -) {
sock_list[i].fd = new_fd;
sock_list[i].addr = client_addr;
break;
}
} fprintf(stderr, "new connect: %d\n", sock_list[i].fd); //将其放入socket的监听集合
FD_SET(new_fd, &watchset);
if (max < new_fd) {
max = new_fd;
} continue;
}else{
for (i = ; i < ; i++) { //data
if (sock_list[i].fd == -)
continue;
if (!FD_ISSET(sock_list[i].fd, &watchset)) {
continue;
} nbytes = recv(sock_list[i].fd, sock_list[i].recvbuf, sizeof(sock_list[i].recvbuf), );
recvbuf[nbytes] = '\0'; printf("recv data is:%s\n",sock_list[i].recvbuf); break;
}
}
}
}//while(1) exit();
}