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的大小。
|