2017-01-27 3 views
0

В моей программе на C мне нужно связаться с двумя серверами: по IP = X1 PORT = X2 и с одним сервером по IP = Y1, PORT = Y2. То есть Я хотел бы иметь возможность писать и читать на обоих серверах в моей программе. .Клиент Socket для двух серверов в C

write(Server1,buffer1); 
read(Server1,buffer1); 
write(Server2,buffer2); 
read(Server2,buffer2); 

Я знаю, как создать единый клиентский сокет для связи с одним сервером, но я не знаю, как должен выглядеть код для общения с ними. Кто-нибудь, кто ведет меня в правильном направлении/покажет мне пример?

С наилучшими пожеланиями Саймон

+0

Возможно, вы можете использовать 'fork' ??? –

ответ

0

Я извиняюсь за плохой английский и дать код для Windows, я не мог писать в Linux сейчас сильных причин, но я надеюсь сделать это в следующий раз.

Хотя версия для Windows может быть немного пугающей вначале, будет ясно, если вы внимательно прочитаете код. Кроме того, вы должны внести некоторые изменения из Windows в версию POSIX Linux, что очень прямо (на примерах, используя потоки POSIX, а не потоки Windows).

Я создал для сокетов, чтобы получать соединения и изменять сообщения в шаблоне recv-send, как вы ожидали. Каждый сервер может получать количество соединений, ограниченных MAX_THREADS (каждый поток управляет одним соединением). Обратите внимание, что select() возвращает сокет сервера, у которого есть ожидающее соединение с вызовом accept().

#include <winSock2.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <WS2tcpip.h> 
#include <stdint.h> 
#include <processthreadsapi.h> 
#include <heapapi.h> 

#define MAX_THREADS 20 
#define MAX_BUFF_SIZE 256 

struct thread_list 
{ 
    HANDLE thread; 
    struct thread_list *next; 
}; 

struct MyData { 
    char name_server[8]; 
    int sock; 
}; 

void log_error(char *msg) 
{ 
    printf(msg); 
    exit(EXIT_FAILURE); 
} 

void initSocket(int *server, struct sockaddr_in *addr, char *ip, uint16_t porta){ 

    if ((*server = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0){ 
     log_error("Erro socket\n"); 
    } 

    addr->sin_port = htons(porta); 
    addr->sin_addr.s_addr = inet_addr(ip); 
    addr->sin_family = AF_INET; 

    if((bind(*server, (struct sockaddr *)&addr, sizeof(struct sockaddr_in)) < 0)) 
     log_error("ERROR bind()"); 

    if(listen(*server, SOMAXCONN) == SOCKET_ERROR) 
     log_error("error listen()"); 

    return; 
} 

DWORD WINAPI ThreadFunc(void *data) 
{ 
    char messageFrom[MAX_BUFF_SIZE], messageTo[MAX_BUFF_SIZE]; 
    struct MyData *ptr = (struct MyData *)data; 

    // pattern: recv - send 
    while(1) 
    { 
     recv(ptr->sock, messageFrom, MAX_BUFF_SIZE, 0); 

     printf(messageFrom); 

     strcpy(messageTo, "Message received. Complete send() message in your way"); 

     send(ptr->sock, messageTo, strlen(messageTo), 0); 
    } 

    // Save the whales, feed the hungry, free the mallocs()'s 
} 


int main(int argc, char **argv) { 
    struct sockaddr_in addr1, addr2; 

    int server1, server2; 

    struct MyData *pDataArray[MAX_THREADS]; 
    DWORD dwThreadIdArray[MAX_THREADS]; 
    HANDLE hThreadArray[MAX_THREADS]; 

    // init num current active threads 
    int num_threads = 0; 

    if(argc < 5) 
     log_error("Format: ./prog ip1 port1 ip2 port2\n"); 

    initSocket(&server1, &addr1, argv[1], (uint16_t)atoi(argv[2])); 
    initSocket(&server2, &addr2, argv[3], (uint16_t)atoi(argv[4])); 

    int evtsock, novosock; 

    fd_set readfds; 

    FD_SET(server1, &readfds); 
    FD_SET(server2, &readfds); 

    struct sockaddr their_addr; 
    socklen_t strg_sz = sizeof(their_addr); 

    while(1) { //escuta conexoes 

     evtsock = select(0, &readfds, NULL, NULL, NULL); 
     pDataArray[num_threads]->sock = accept(evtsock, &their_addr, &strg_sz); 

     if(pDataArray[num_threads]->sock == INVALID_SOCKET) 
      log_error("ERROR accept()"); 

     if(num_threads == MAX_THREADS){ 
      // now this program will run forever. It is recommended to manage signals like SIGTERM 
      // free mallocated memory and release all resources carefully 
      printf("Max connections reached\n"); 
      continue; 
     } 

     pDataArray[num_threads] = (struct MyData *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 
      sizeof(struct MyData)); 

     if(evtsock == server1) 
      strcpy(pDataArray[num_threads]->name_server, "server1"); 
     else if(evtsock == server1) 
      strcpy(pDataArray[num_threads]->name_server, "server2"); 
     else 
      printf("Unmanaged event\n"); 

     hThreadArray[num_threads] = CreateThread(NULL, 0, ThreadFunc, &pDataArray[num_threads], 0, NULL); 

     num_threads++; 
    } 

    return 0; 
} 

 Смежные вопросы

  • Нет связанных вопросов^_^