2015-03-27 4 views
0

Я пытаюсь создать базовый сервер, который поддерживает несколько клиентов. Я хочу, чтобы главный сервер подключался к двум клиентам, а затем отключал и передавал файловые дескрипторы для клиентов другой программе через вызов execl. Оба клиента подключаются к серверу и могут общаться с ним (проверяется путем запроса клиентов для имен пользователей или дескрипторов), но когда я пытаюсь передать клиентов ко второй программе (которая предназначена для личного сервера между клиенты, чтобы провести матч с настольной игрой), на выходе клиента не отображается вывод, когда вторая программа пытается связаться с ними, я уверен, что именно так я пытаюсь передать информацию о соединении. Приветствуется всякая помощь в правильном прохождении соединений.C: Соединение сокетов через execl

Вот код для основного сервера после того, как она принимает два соединения:

Основной сервер: Примечание. Добавлена ​​дополнительная проверка ошибок, как рекомендовано.

if(fork() == 0){ 
     close(listener); 
     int nBytes; 
     char* playerOne[20]; 
     char* playerTwo[20]; 

     //Creates strings to hold file descriptor information for execl 
     char connAscii[sizeof(int)]; 
     char connAscii2[sizeof(int)]; 
     snprintf(connAscii,sizeof(conn), "%d", conn); 
     snprintf(connAscii2,sizeof(conn2), "%d", conn2); 
     fprintf(stderr, "Int conn: %d, asciiConn: %s, backToInt: %d", conn, connAscii, atoi(connAscii)); 
     char *argf[2]; 
     argf[0] = connAscii; 
     argf[1] = connAscii2; 


     //Send Handle Request to Connection 1 
     nBytes = send(conn, handleRequest, sizeof(handleRequest),0); 
     if(nBytes == -1){ 
      perror("send"); 
      exit(1); 
     } 
     //Receive Handle from Connection 1 
     nBytes = recv(conn, playerOne, 20, 0); 
     if(nBytes == -1){ 
      perror("recv"); 
      exit(1); 
     } 
     //Send Handle Request to Connection 2 
     nBytes = send(conn2, handleRequest, sizeof(handleRequest),0); 
     if(nBytes == -1){ 
      perror("send"); 
      exit(1); 
     } 
     //Receive Handle from Connection 2 
     nBytes = recv(conn2, playerTwo, 20, 0); 
     if(nBytes == -1){ 
      perror("recv"); 
      exit(1); 
     } 
     //Send Handle for Connection 2 to Connection 1 
     nBytes = send(conn, playerTwo, sizeof(playerTwo),0); 
     if(nBytes == -1){ 
      perror("send"); 
      exit(1); 
     } 
     //Send Handle for Connection 1 to Connection 2 
     nBytes = send(conn2, playerOne, sizeof(playerOne),0); 
     if(nBytes == -1){ 
      perror("send"); 
      exit(1); 
     } 

     //Passes file descriptors to nimMatch 
     execl("nimMatch", "nimMatch", argf, (char *)0); 
    } 

Персональный сервер (другой файл .c, отличный от основного): Примечание. Добавлены отладки заявления

char greet[] = {"Hello players, please wait for match setup."}; 
    int main(int argc, char *argv[]) { 
    int conn1 = atoi(argv[1]); 
    int conn2 = atoi(argv[2]); 
    int sent; 
    fprintf(stderr, "Attempting connection\n"); 
    sent = send(conn1, greet,sizeof(greet),0); 
    if(sent == -1){ 
     perror("send"); 
     exit(1); 
    } 
    return 0; 
} 

И код клиента после того, как он был связан и совпадающая с противником:

printf("Your opponent is: %s\n\n Connecting to match server...",  otherHandle); 
memset(&buf[0],0,sizeof(buf)); 
if ((numbytes = recv(sockfd, buf, 99, 0)) == -1) { //should come from personal server 
     perror("recv"); 
     exit(1); 
    } 
printf("From match server: %s\n", buf); 

Если больше кода необходимо, дайте мне знать, я знаю, что клиенты успешно подключиться к сервер, и я не получаю ошибок при компиляции или запуске.

Предлагаемый ответ от EJP гарантирует, что частный сервер получит правильный ввод, но клиент, похоже, не сохраняет строку с частного сервера. Скорректированный клиентский код ниже указывает, что клиент получает 64 байта, но buf пуст.

printf("You're opponent is: %s\n\n Connecting to match server...", otherHandle); 
memset(&buf[0],0,sizeof(buf)); 
numbytes = recv(sockfd, buf, 99, 0); 
if (numbytes == -1) { 
     perror("recv"); 
     exit(1); 
    } 
if(strlen(buf) < 1) 
    fprintf(stderr, "No buffer input, found %d bytes\n", numbytes); 
printf("From match server: %s\n", buf); 
+3

Вы не проверяете значения, возвращаемые send() и recv(). Не проверяя эти значения, вы не знаете, сколько байтов было действительно отправлено или получено, и, не зная этого, ваша программа не может работать надежно. В частности, вы не должны думать, что send() и recv() возвратят либо ошибку, либо количество байтов, которые вы передали; они могут (и иногда будут) возвращать неотрицательное значение, которое меньше числа байтов, которое вы передали, с указанием частичной отправки или получения. –

+0

@JeremyFriesner Спасибо, я не знал этого, я новичок в сетевом программировании, и я изменю его в своем коде. Однако я не считаю, что это часть этой точной проблемы, потому что клиенты, похоже, ничего не получают от сервера сопоставления. Но спасибо, что спасли мне будущую головную боль. – CSjunkie

+0

Кажется, что сервер сопоставления (3-й блок кода) повесился на команду отправки. – CSjunkie

ответ

2

можно передать аргументы execl() неправильно. Он не принимает массив аргументов, он принимает список аргументов varargs. Это должно быть

execl(path, connAscii, connAscii2, (char*)0); 
+0

. Спасибо, теперь сервер соответствия получает дескриптор файла правильно, но клиенты не отображают обратную связь с сервера сопоставления, однако теперь сервер соответствия мимо отправить. – CSjunkie

+0

Ну, это в клиентском коде, где он говорит printf («From match server% s \ n», buf) он печатает с сервера сопоставления, но не buf – CSjunkie

+0

Это должно быть 'printf (« From match server% . * s \ n, numbytes, buf); 'Вам не нужно' memset() ', а тест' strlen() 'недействителен: удалите его. – EJP

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