在分布式处理系统中,单个任务可能有多台机器来共同完成,所以经常要登录多台服务器如redis等等
以下程序提供同时连接多台服务器,同时向这些服务器发送数据的功能
#include<stdio.h> #include<sys/types.h> #include<sys/socket.h> #include<stdlib.h> #include<string.h> #include <netinet/in.h> //存储服务器信息 typedef struct Server{ int sockfd; char raw[100]; char address[20]; int port; } Server; Server *servers;//存储所有服务器的数组指针 int server_count;//总共有几台server void help(char *s){ printf("example:\n" "\t%s 127.0.0.1:6379 127.0.0.1:6378 192.168.1.1:6379\n" "\t%s -f server.conf\n\n", s, s ); } void ana_addr(char *addr, Server *s){ char *p = addr, *q = s->address; while(*p != '\0'){ if(*p == ':') break; *q++ = *p++; } if(*p == '\0'){ printf("Not find port at address:%s\n", addr); exit(1); } *q = '\0'; s->port = atoi(++p); sprintf(s->raw, "%s:%d", s->address, s->port); } int main(int argc, char *argv[]){ int i; server_count = 0; if(argc == 1){ help(argv[0]); exit(1); } if(strcmp(argv[1], "-h") == 0){ help(argv[0]); exit(1); } if(strcmp(argv[1], "-f") == 0 && argc >= 3){ //从文件读取服务器配置信息 FILE *file; file = fopen(argv[2], "r"); if(!file){ printf("Could not open file:%s\n", argv[2]); exit(2); } char line[100]; int size = 0; while(fgets(line, 100, file)){ if(server_count == size){ size += 5; servers = (Server *) realloc(servers, size * sizeof(Server)); if(!servers){ printf("Memory error\n"); exit(1); } } if(strlen(line) < 6) continue; ana_addr(line, servers + server_count); server_count++; } }else{ //处理由命令行传进来的服务器信息 server_count = argc - 1; servers = (Server *) malloc(server_count * sizeof(Server)); if(!servers){ printf("Memory error\n"); exit(1); } for(i = 1; i < argc; i++){ ana_addr(argv[i], servers + i - 1); } } for(i = 0; i < server_count; i++){ int s = socket(PF_INET, SOCK_STREAM, 0); if(s == -1){ printf("Create socket error!\n"); exit(1); } servers[i].sockfd = s; struct sockaddr_in server_addr; bzero(&server_addr,sizeof(server_addr)); server_addr.sin_family=AF_INET; server_addr.sin_port=htons(servers[i].port); if(inet_aton(servers[i].address, &server_addr.sin_addr) == 0){ printf("Address error:%s\n", servers[i].address); exit(1); } int c = connect(s, (struct sockaddr*) &server_addr, sizeof(struct sockaddr)); if(c == -1){ printf("Connect Error: %s\n", servers[i].raw); exit(1); } printf("Connect to %s...ok\n", servers[i].raw); } do{ char command[1024], msg[10240]; int nbyte; printf(">"); fgets(command, 1024, stdin); if(command[0] == '\n') continue; i = strlen(command); strcpy(command + i -1 , "\r\n"); for(i = 0; i < server_count; i++){ if(write(servers[i].sockfd, command, strlen(command)) == -1){ printf("send error!\n"); exit(1); } } for(i = 0; i < server_count; i++){ if((nbyte = read(servers[i].sockfd, msg, 1024)) != -1){ msg[nbyte] = '\0'; printf("=========================================>from %s\n%s", servers[i].raw, msg); }else{ printf("read error!\n"); exit(1); } } if(strcmp(command, "quit\r\n") == 0){ break; } } while(1); printf("end\n"); }
此程序提供两种参数格式
1)以文件形式的服务器配置,每一行为address:port
./mtelnet -f servers.conf
2)直接在参数里加服务器配置
./mtelnet 127.0.0.1:6379 127.0.0.1:6378
连接成功后就可以按照提示输入要发送的数据。返回结果分行显示。