在分布式处理系统中,单个任务可能有多台机器来共同完成,所以经常要登录多台服务器如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

 

连接成功后就可以按照提示输入要发送的数据。返回结果分行显示。

 

 posted on 2012-12-24 17:43  so_  阅读(607)  评论(0编辑  收藏  举报