(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 就可以了…