(linux平台)本人想通过accept的返回值来判断是来自不同的客户端和服务器建立的socket,但是为什么每次的client_sockfd返回值都是一样的啊?但是通过remote_addr存储的ip地址和端口号打印出来的结果可以看出是不同的客户端。那么本人想问一下本人想实现client1 发送数据给client2 不是在服务器存储accept的返回值来记录吗?本人也通过了ip和port实现存储不同的客户端,但是转发的时候总是从发回到了自身?请大家给本人解惑,不甚感激!
int main(){ int server_sockfd;//服务器端套接字 int client_sockfd; int len; struct sockaddr_in my_addr; struct sockaddr_in remote_addr; socklen_t sin_size; char buf[BUFSIZ]; char sendMsg[BUFSIZ]; pid_t pid; map<struct sockaddr_in *,string> socket_table; typedef map<struct sockaddr_in*,string>::iterator socket_table_iterator; memset(&my_addr,0,sizeof(my_addr)); my_addr.sin_family=AF_INET; my_addr.sin_addr.s_addr=INADDR_ANY; my_addr.sin_port=htons(8000); if((server_sockfd=socket(PF_INET,SOCK_STREAM,0))<0){ perror("create socket error!!!"); exit(1); } if(bind(server_sockfd,(struct sockaddr *)&my_addr,sizeof(struct sockaddr))<0){ perror("bind socket error!!!"); exit(1); } listen(server_sockfd,5); sin_size=sizeof(struct sockaddr_in); while(1){ client_sockfd=accept(server_sockfd,(struct sockaddr*)&remote_addr,&sin_size); cout<<"client_sockfd"<<client_sockfd<<endl; if(client_sockfd<0){ perror("accept socket error!!!"); exit(1); } pid=fork(); if(pid==0){ close(server_sockfd); cout<<"client_sockfd: "<<client_sockfd<<"\tport:"<<remote_addr.sin_port<<endl; while((len=recv(client_sockfd,buf,BUFSIZ,0))>0){ buf[len]="\0"; printf("buf=%s\n",buf); socket_table_iterator iter=socket_table.find (client_sockfd); if(is_device (buf,iter)==0){ user_data_process(buf,sendMsg,len); }else if(is_device (buf,iter)==1){ cout<<"user client"<<endl; user_data_process_user2device(buf,client_sockfd,sendMsg,len,socket_table); } printf("sendMsg=%s\n",sendMsg); if(send(client_sockfd,sendMsg,len,0)<0){ perror("write error!!!"); exit(1); } } } close(client_sockfd); } }
解决方案
60
你是每个连接创建一个进程处理, 每 accept 一个 fd , 创建了一个进程, 然后 close fd, 所以下一次 accept 获得 fd 又会是 原来的 值, 你应该做的是 每 accept 一个 fd , 就把这个fd 添加到一个 hash_map<user::info, socket::fd> 的结构中, 而不是开一个新的进程, 你收到数据以后, 就可以根据用户信息, 查找 hash 表, 得到对应用户的 fd, 然后 write 就可以了..
假如你的连接很多, 例如超过 1000 个, 就应该 epoll, 假如比较少, 不到 1000 个, select poll 就可以了…