|  
 
 
centos6.4(64位)环境下,使用select方式处理socket,accept第一次连接时无法获取客户端ip(在32位环境下可以正常获取客户端ip)。烦请有经验的解释下其中的原委!代码如下:  #include <stdio.h> #include <string.h> #include <errno.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <unistd.h> #include <fcntl.h>   #define LISTEN_IP "0.0.0.0" #define LISTEN_PORT 818 #define MAX_SOCKFD 10 #define BUFFER_SIZE 256   int main(int argc, char *argv[]) {     int sockfd;     struct sockaddr_in server_addr;     int is_connected[MAX_SOCKFD] = {0,};     fd_set readfds;     int fd;     int newfd;     struct sockaddr_in client_addr;     socklen_t addr_len;     char buffer[BUFFER_SIZE];     int optval = 1;       sockfd = socket(AF_INET, SOCK_STREAM, 0);     if(sockfd  < 0) {         printf("[%d] %s\n", errno, strerror(errno));         return 1;     }     if(!setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)) < 1) {         printf("[%d] %s\n", errno, strerror(errno));         return 1;     }       bzero(&server_addr, sizeof(server_addr));     server_addr.sin_family = AF_INET;     server_addr.sin_port = htons(LISTEN_PORT);     inet_aton(LISTEN_IP, &server_addr.sin_addr);     //server_addr.sin_addr.s_addr = htonl(INADDR_ANY);     if(bind(sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {         printf("[%d] %s\n", errno, strerror(errno));         return 1;     }       if(listen(sockfd, 20) < 0) {         printf("[%d] %s\n", errno, strerror(errno));         return 1;     }     printf("[%d] listen at %s:%d\n", sockfd, LISTEN_IP, LISTEN_PORT);       while(1) {         FD_ZERO(&readfds);         FD_SET(sockfd, &readfds);         for(fd = 0; fd < MAX_SOCKFD; fd++) {             if(is_connected[fd]) FD_SET(fd, &readfds);         }         if(select(MAX_SOCKFD, &readfds, NULL, NULL, NULL) < 0) {             printf("[%d] %s\n", errno, strerror(errno));             return 1;         }         for(fd = 0; fd < MAX_SOCKFD; fd++) {             if(!FD_ISSET(fd, &readfds)) continue;             if(fd == sockfd) {                 newfd = accept(fd, (struct sockaddr *)&client_addr, &addr_len);                 getpeername(fd, (struct sockaddr *)&client_addr, &addr_len);                 if(newfd < 0) {                     printf("[%d] %s\n", errno, strerror(errno));                     return 1;                 }                 is_connected[newfd] = 1;                 printf("[%d] connected from %s:%d\n", newfd,                        inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port));             } else {                 bzero(buffer, sizeof(buffer));                 if(read(fd, &buffer, sizeof(buffer)) <= 0) {                     is_connected[fd] = 0;                     close(fd);                     printf("[%d] connection closed\n", fd);                 } else {                     printf("[%d] msg: %s\n", fd, buffer);                 }             }         }     }       return 0; }  
客户端测试代码如下:  <?php $fd = fsockopen("localhost", 818, $errno, $errstr, 10); if(!$fd) exit("[$errno] $errstr\n"); $data = "socket client!"; fwrite($fd, $data, strlen($data)); fclose($fd);  
结果如下:  [3] listen at 0.0.0.0:818 [4] connected from 0.0.0.0:0 [4] msg: socket client! [4] connection closed [4] connected from 127.0.0.1:37186 [4] msg: socket client! [4] connection closed  addr_len需要赋值,就是client_addr的大小。  
 |