您的当前位置:首页正文

linux select函数 写一个服务器,转发数据

2024-11-26 来源:个人技术集锦

linux select函数 写一个服务器,转发数据

源码:

#include <sys/types.h> 
#include <sys/socket.h> 
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <netinet/in.h> 
#include <sys/time.h> 
#include <sys/ioctl.h> 
#include <unistd.h> 


#define PORT_SERV 8888

#define BUFFSIZE 1024
char receiveBuff[BUFFSIZE]={0};

#include <map>
#include <list>
#include <string>
std::list<int> clentFDs;
std::map<int,std::string> clientFD_buff_map;
#include<iostream>
using namespace std;

int main() 
{ 
	int server_sockfd, client_sockfd; 
	int server_len, client_len; 
	struct sockaddr_in server_address; 
	struct sockaddr_in client_address; 
	int result; 

    //--读取集合,测试集合
    fd_set readfds, testfds;

    //--建立服务器端socket
    server_sockfd = socket(AF_INET, SOCK_STREAM, 0);
	server_address.sin_family = AF_INET; 
	server_address.sin_addr.s_addr = htonl(INADDR_ANY); 
    server_address.sin_port = htons(PORT_SERV);
	server_len = sizeof(server_address); 

	bind(server_sockfd, (struct sockaddr *)&server_address, server_len); 
	listen(server_sockfd, 5); 

    //--
    FD_ZERO(&readfds);
    //--将服务器端socket加入到读取集合中
    FD_SET(server_sockfd, &readfds);

    printf("server runing \n");
    fflush(stdout);

	while(1) 
	{       
		int fd; 
		int nread; 
		testfds = readfds; 

		/*阻塞,测试文件描述符变动 */
		result = select(FD_SETSIZE, &testfds, (fd_set *)0,(fd_set *)0, (struct timeval *) 0); 
		if(result < 1) 
		{ 
            perror("server error : select() result < 1");
            fflush(stdout);
			exit(1); 
		} 

        /*扫描所有的文件描述符*/
		for(fd = 0; fd < FD_SETSIZE; fd++) 
		{
			/*找到相关文件描述符*/
			if(FD_ISSET(fd,&testfds)) 
			{ 
                /*判断是否为服务器套接字,是则表示为客户请求连*/
				if(fd == server_sockfd) 
				{ 
					client_len = sizeof(client_address); 
                    client_sockfd = accept(server_sockfd,(struct sockaddr *)&client_address, (socklen_t *)&client_len);

                    //将客户端socket加入到集合中
                    FD_SET(client_sockfd, &readfds);
                    printf("adding client on fd %d\n", client_sockfd);
                    fflush(stdout);

                    clentFDs.push_back(client_sockfd);
				} 

				/*客户端socket中有数据请求时*/
                else
                {
                    //取得数据量交给nread
                    ioctl(fd, FIONREAD, &nread);

					/*客户数据请求完毕,关闭套接字,从集合中清除相应描述符 */
					if(nread == 0) 
					{ 
						close(fd); 
						FD_CLR(fd, &readfds); 
                        printf("removing client on fd %d\n", fd);
                        fflush(stdout);
                        clentFDs.remove(fd);
					} 

					/*处理客户数据请求*/
					else 
					{ 
                        read(fd, &receiveBuff, nread);
                        sleep(2);
                        printf("client fd %d, receiveBuff :\n", fd);
                        printf("%s\n", receiveBuff);
                        fflush(stdout);

                        clientFD_buff_map.insert(std::pair<int,std::string>(fd,(std::string)receiveBuff));

                        memset(receiveBuff,0,BUFFSIZE);
                        /* 清空文件 */
                        ftruncate(fd,0);
                        /* 重新设置文件偏移量 */
                        lseek(fd,0,SEEK_SET);

					} 

                    //--服务器转发
                    std::map<int,std::string>::iterator it;
                    std::list<int>::iterator listIt;
                    for (listIt=clentFDs.begin();listIt!=clentFDs.end();listIt++) {

                        for (it = clientFD_buff_map.begin();it!=clientFD_buff_map.end();it++) {
                             if(it->first != *listIt){
                                std::cout<< "client "<<it->first << " => " << it->second << '\n';
                                write(*listIt, it->second.c_str(), it->second.length());
                             }
                        }
                    }
                    clientFD_buff_map.clear();

                }

            }

        }//for
    }//while
} 

ps:

买了一台百度云服务器,ubuntu16.04lts ,公网ip
然后搭建了FTP 服务器,
把源码放到服务器上面编译
运行服务端以上程序
然后 自己写的 QtAndroid tcp客户端
运行在 家里面的pc机上面的tcp客户端通信 ,就像qq功能,只是一个示范

显示全文