2016-05-04 3 views
0

ソケットプログラミングを試みています。私はgoogleをして、私のような問題を見た。しかし、私は自分の誤りを理解することはできません。接続のソケットプログラミングエラー

コードを実行するたびにmainconnect()のエラーが表示され、client.cになります。エラーはinvalid argumentです。

Server.c

/* chatroom server */ 

#include <stdio.h> 
#include <stdlib.h> 
#include <sys/types.h> 
#include <sys/socket.h> 
#include <netinet/in.h> 
#include <arpa/inet.h> 
#include <string.h> 
#include <unistd.h> 
#include <netdb.h> 
#include <pthread.h> 
#include <signal.h> 


#define MAX_ROOMS 36 
#define MAX_NAME_SIZE 56 
#define PORT_NUM 12333 
#define MSG_SIZE 8 
#define MAX_LOAD 246 
#define MAX_CRC 64 //max clients 
#define MAX_BUF 256 
#define SERVER_IP 32 
#define DEBUG 0 

struct msg { 
    int type; //create, join, delete 
    int length; // length or port num 
}; 

struct chat_room { 
    int socket_d; //socket descriptor 
    int port; 
    pthread_t id; //id of chatroom 
    char name[MAX_NAME_SIZE]; 
    int clients[MAX_ROOMS]; // used to hold the client's master sockets 
}; 

struct chat_room* findRoom(char* name, struct chat_room* chat){ 

    int iterator; 

    for(iterator = 0; iterator < MAX_ROOMS; iterator++){ 
     if(strcmp(name, chat[iterator].name) && (chat[iterator].port != 0)) { 
      return &chat[iterator]; 
     } 
    } 

    //if room does not exist 
    return NULL;  
} 

struct chat_room* joinServer(int chat_socket, char* name, struct chat_room* chat){ 

    struct chat_room* local_chat = findRoom(name, chat); 
    int i; 
    if(local_chat != NULL){ //if the chat exists 
     for(i= 0; i< MAX_CRC; i++){ 
      if(local_chat->clients[i] == 0) 
      { 
       local_chat->clients[i] = chat_socket; 
      } 
      return local_chat; 
     } 
    } 

    //if server if full or else error 
    return NULL; 
} 

int createResponse(int chat_socket, int new_port_num, int type){ 
    struct msg temp; 
    char temp_buff[MAX_LOAD]; 

    memset(temp_buff, 0, MAX_LOAD); 
    temp.type = type; 
    temp.length = new_port_num; 

    memcpy(temp_buff, &temp, sizeof(temp)); 

    write(chat_socket, temp_buff, MSG_SIZE); 

    return 0; 
} 

int joinResponse(int chat_socket, int new_port_num){ 
    struct msg temp; 
    char temp_buff[MAX_LOAD]; 

    memset(temp_buff, 0, MAX_LOAD); 
    temp.type = 11; 
    temp.length = new_port_num; 

    memcpy(temp_buff, &temp, sizeof(temp)); 

    write(chat_socket, temp_buff, MSG_SIZE); 

    return 0; 
} 

int deleteResponse(int chat_socket, struct chat_room* chat){ 
    struct msg temp; 
    char temp_buff[MAX_LOAD]; 
    int i; 
    memset(temp_buff, 0, MAX_LOAD); 
    temp.type = 12; 

    memcpy(temp_buff, &temp, sizeof(temp)); 

    for(i=0; i<MAX_CRC; i++){ 
     if((chat->clients[i] != chat_socket) && (chat->clients[i] != 0)) 
      write(chat->clients[i],temp_buff, MSG_SIZE); 
    } 

    return 0; 
} 

struct chat_room* addRoom(int chat_socket, char* name, struct chat_room* chat){ 

    int socket_d; 
    int i; 
    struct sockaddr_in sock; 

    static int port = PORT_NUM; 

    memset(&sock, 0, sizeof(sock)); 

    int temp = -1; 

    for(i = 0; i<MAX_ROOMS; i++){ 
     if((strcmp(chat[i].name, name) == 0) && (chat[i].port != 0)){ 
      createResponse(chat_socket, chat[i].port, 15); 
      return NULL; 
     } 
     else if((chat[i].port == 0) && (temp== -1)){ 
      temp = i; 
     } 
    } 

    if(temp == -1){ 
     return NULL; 
    } 

    socket_d = socket(AF_INET, SOCK_STREAM, 0); 

    if(socket_d == -1 && DEBUG){ 
     perror("Error creating chatroom socket"); 
     return NULL; 
    } 

    sock.sin_family = AF_INET; 
    port++; 
    sock.sin_port = htons(port); 

    if(bind(socket_d, (struct sockaddr*)&sock, sizeof(struct sockaddr_in)) == -1){ 
     perror("error in binding "); 
     return NULL; 
    } 

    chat[temp].socket_d = socket_d; 
    chat[temp].port = port; 
    strcpy(chat[temp].name, name); 

    return &chat[temp]; 

} 

void* chat_room_main(void* chat_room_cluster){ 

    char buf[MAX_LOAD]; 

    int socket_d, chat_socket; 
    int temp; //temp_fd 
    int read_val; 
    int num_clients = 0; 
    int i; 
    int clients[MAX_CRC]; 

    fd_set allfd, modfd; 

    struct chat_room chat_room_para; 

    memcpy(&chat_room_para, (struct chat_room*)chat_room_cluster, sizeof(struct chat_room)); 
    free(chat_room_cluster); 

    memset(clients, 0, sizeof(int)*MAX_CRC); 
    socket_d = chat_room_para.socket_d; 

    listen(socket_d, 1); 

    FD_ZERO(&allfd); 
    FD_SET(socket_d, &allfd); 
    printf("New Chatroom Started\n"); 
    while(1){ 
     modfd = allfd; 
     select(FD_SETSIZE, &modfd, NULL, NULL, NULL); 

     for(temp = 0; temp < FD_SETSIZE; temp++){ 
      if(FD_ISSET(temp, &modfd)){ 

       memset(buf, 0, sizeof(buf)); 

       if(temp == socket_d) { 

        chat_socket = accept(socket_d, NULL, NULL); 
        FD_SET(chat_socket, &allfd); 


        // find an empty spot to add the chat room 
        for(i = 0; i<MAX_CRC; i++) { 
         if(clients[i] == 0){ 
          clients[i] = chat_socket; 
          break; 
         } 
        } 

        sprintf(buf, "Number of people in chatroom: %d", num_clients); 
        write(chat_socket, buf, strlen(buf)); 
        num_clients++; 
       } 
       else{ 
        if(read_val = read(temp, buf, MAX_LOAD) > 0){ 
         for(i = 0; i< MAX_CRC; i++){ 
          if((clients[i] != temp) && (clients[i] != 0)){ 
           write(clients[i], buf, read_val); 
          } 
         } 
        } 
        else if(read_val <= 0) { 
         FD_CLR(temp, &allfd); 

         for(i = 0; i<MAX_CRC; i++){ 
          if(clients[i] == temp) 
           clients[i] = 0; 
         } 
         num_clients--; 
         close(chat_socket); 
        } 
       } 
      } 
     } 
    } 

} 

int main(int argc, char* argv[]){ 

    int server_socket, chat_socket; //file descriptors for server and chat 
    int temp; //tempfd 
    int i, j; 

    char server_ip[SERVER_IP]; 
    char buf[MAX_BUF]; 
    char msg_buf[MSG_SIZE]; 

    fd_set allfd, modfd; 

    struct sockaddr_in sock; 
    struct hostent* host_name; 

    struct chat_room chatrooms[MAX_ROOMS]; 

    memset(chatrooms, '\0', sizeof(struct chat_room)* MAX_ROOMS); 
    memset(&sock, '\0', sizeof(sock)); 

    server_socket = socket(AF_INET, SOCK_STREAM, 0); 
    if(server_socket == -1){ 
     perror("Error creating socket"); 
     return -1; 
    } 

    sock.sin_family = AF_INET; 
    sock.sin_port = htons(PORT_NUM); 
    sock.sin_addr.s_addr = INADDR_ANY; 

    if((bind(server_socket, (struct sockaddr*)&sock, sizeof(struct sockaddr_in))) == -1){ 
     perror("Error in bind()"); 
     return -1; 
    } 

    listen(server_socket, 1); 

    FD_ZERO(&allfd);  
    FD_SET(server_socket, &allfd); 
    FD_SET(0, &allfd); 
    printf("\n*******Chatroom Server*******"); 
    while(1){ 
     modfd = allfd; 
     select(FD_SETSIZE, &modfd, NULL, NULL, NULL); 

     for(temp = 0; temp < FD_SETSIZE; temp++) { 
      if(FD_ISSET(temp, &modfd)) { 
       switch(temp){ 
        case 0: 
         break; 
        default: 
         if(temp == server_socket){ 
          chat_socket = accept(server_socket, NULL, NULL); 
         } 
         else{ 
          char msg_buf[MSG_SIZE]; 
          char buf[MAX_LOAD]; 
          char name[MAX_LOAD]; 

          struct msg temp_message; 
          struct chat_room* local_chat = NULL; 

          void* (*init_chatroom)() = &chat_room_main; 
          void* thread_args; 

          pthread_attr_t attr; 
          pthread_t tid; 

          pthread_attr_init(&attr); 
          pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 

          memset(buf, 0, sizeof(buf)); 
          memset(msg_buf, 0, sizeof(msg_buf)); 
          msg_buf[19]= 0; 

          int read_val = read(temp, msg_buf, MSG_SIZE); 
          if(read_val > 0){ 
           memcpy(&temp_message, msg_buf, sizeof(temp_message)); 
           read(temp, buf, temp_message.length - sizeof(temp_message)); 
           memcpy(name, buf, temp_message.length - sizeof(temp_message)); 

           if(temp_message.type == 0) {//if create 
            local_chat = addRoom(temp, name, chatrooms); 

            if(local_chat != NULL){ 
             thread_args = (void*)malloc(sizeof(struct chat_room)); 
             memcpy((struct chat_room*) thread_args, local_chat, sizeof(struct chat_room)); 
             pthread_create(&tid, &attr, init_chatroom, thread_args); 
             local_chat->id = tid; 
             createResponse(temp, local_chat->port, 10); 
            } 

           } 
           else if(temp_message.type == 1){ //join 
            local_chat = joinServer(temp, name, chatrooms); 

            if(local_chat != NULL){ 
             joinResponse(temp, local_chat->port); 
            } 

           } 
           else if(temp_message.type == 2){ //delete 
            local_chat = findRoom(name, chatrooms); 

            printf("Deleting Room\n"); 
            if(local_chat != NULL) { 
             local_chat->port = 0; 
             close(local_chat->socket_d); 
             deleteResponse(temp, local_chat); 

             for(j = 0; j<MAX_CRC; j++){ 
              if(local_chat->clients[j]!=0) { 
               FD_CLR(local_chat->clients[j], &modfd); 
               local_chat->clients[j] = 0; 
              } 
             } 
             pthread_cancel(local_chat->id); 
            } 
           } 

          } 
          else if(read_val <= 0){ 
           FD_CLR(temp, &allfd); 

           close(temp); 
          } 
         } 
       } 
      } 
     } 
    } 

    return 0; 

} 

いるclient.c

#include <stdio.h> 
#include <stdlib.h> 
#include <sys/types.h> 
#include <sys/socket.h> 
#include <netinet/in.h> 
#include <arpa/inet.h> 
#include <string.h> 
#include <unistd.h> 
#include <netdb.h> 
#include <pthread.h> 

#define PORT_NUM 12333 
#define MSG_SIZE 8 
#define MAX_LOAD 246 
#define MAX_BUF 256 
#define SERVER_IP 32 

struct msg { 
    int type; 
    int length; 
}; 

struct thread_para { 
    int port; 
    struct hostent* host_name; 

}; 

int sendCmd(int chat_socket, char* buf, int type){ //function for sending the command 
    struct msg temp; 
    char temp_buf[MAX_LOAD]; 
    char name[MAX_LOAD]; 

    int iterator; 

    if(type == 0){ 
     iterator = 6; 
    } 
    else if(type == 1){ 
     iterator = 4; 
    } 
    else if(type == 2){ 
     iterator = 6; 
    } 

    for(; iterator < strlen(buf); iterator++){ 
     if(buf[iterator] == ' ') { 
      continue; 
     } 
     else{ 
      break; 
     } 
    } 

    strcpy(name, buf+iterator); 
    memset(temp_buf, 0, MAX_LOAD); 
    temp.type = type; 
    temp.length = sizeof(temp)+strlen(name)+1; //for \0 


    memcpy(temp_buf, &temp, sizeof(temp)); 
    memcpy(temp_buf+sizeof(temp), name, strlen(name)+1); 

    write(chat_socket, temp_buf, temp.length); 

    return 0; 

} 

void* connectChat(int port_num, struct hostent* host_name, int master){ 
    char buf[MAX_BUF]; 
    char temp_buf[MAX_BUF]; 

    int chat_socket; 
    int i; 
    int input; 
    int temp; //temp fd 

    fd_set allfd, modfd; 

    struct sockaddr_in sock; 

    printf("Successfully Joined Room\n"); 
    memset(buf, 0, sizeof(buf)); 
    memset(&sock, 0, sizeof(sock)); 
    sock.sin_family = AF_INET; 
    sock.sin_port = htons(port_num); 
    memcpy((char*)&sock.sin_addr.s_addr, host_name->h_addr, host_name->h_length); 

    chat_socket = socket(AF_INET, SOCK_STREAM, 0); 
    if(chat_socket == -1){ 
     perror("Error in creation"); 
     return NULL; 
    } 

    if(connect(chat_socket, (struct sockaddr*)&sock, sizeof(struct sockaddr)) < 0){ 
     perror("Error in connection"); 
     return NULL; 
    } 

    FD_ZERO(&allfd);   
    FD_SET(chat_socket, &allfd);  
    FD_SET(0, &allfd);  
    FD_SET(master, &allfd); 

    while(1) { 
     modfd = allfd; 
     select(FD_SETSIZE, &modfd, NULL, NULL, NULL); 

     for(temp = 0; temp< FD_SETSIZE; temp++){ 

      memset(buf, 0, sizeof(buf)); 
      memset(temp, 0, sizeof(buf)); 

      if(temp == 0) { //reading from standard in 
       input = read(0, buf, MAX_BUF); 
       buf[input-1] = '\0'; //add termination to end 
       write(chat_socket, buf, strlen(buf)); 

      } 
      else if(temp == chat_socket){ 
       input = read(0, buf, MAX_BUF); 
       buf[input] = '\0'; 

       memcpy(temp, buf, input); 
       //display message 
       printf("%s \n", temp_buf); 
      } 
      else if(temp == master){ 
       struct msg temp_message; 
       input = read(temp, buf, MSG_SIZE); 
       memcpy(&temp_message, buf, MSG_SIZE); 
       if(temp_message.type == 12){ 
        printf("Chatroom has been deleted, Shutting down chatroom\n"); 
        return NULL; 
       } 
      } 
     } 
    } 

    return 0; 
} 

int main(int argc, char* argv[]){ 

    char buf[MAX_BUF]; 

    int chat_socket; 
    int i; 
    int input; 
    int temp; //temp fd 
    int accept_input = 1; // take input for stdin to create a chat thread 

    fd_set allfd, modfd; 

    char server_ip[SERVER_IP]; 
    struct hostent* host_name; 
    struct sockaddr_in sock; 


    struct msg temp_message; 

    pthread_attr_t tattr; 
    pthread_t tid; 

    if(argc < 2) { 
     printf("Please try ./crc <server IP> \n"); 
     return -1; 
    } 

    pthread_attr_init(&tattr); 
    pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED); 

    memset(&sock, '\0', sizeof(sock)); 
    sock.sin_family = AF_INET; 
    sock.sin_port = htons(PORT_NUM); 
    strcpy(server_ip ,argv[1]); 


    if((host_name = (struct hostent*)gethostbyname(server_ip)) == NULL){ 
     perror("failed to get host name"); 
     return -1; 
    } 

    memcpy((char*)&sock.sin_addr.s_addr, host_name->h_addr, host_name->h_length); 

    chat_socket = socket(AF_INET, SOCK_STREAM, 0); 
    if(chat_socket == -1){ 
     perror("Error creating socket"); 
     return -1; 
    } 

    if((connect(chat_socket, (struct sockaddr*)&sock, sizeof(sock))) < 0) { 
     perror("Error connecting"); 
     return -1; 
    } 

    FD_ZERO(&allfd);  /* first, clear the allfd set */ 
    FD_SET(chat_socket, &allfd); /* adding client to the set */ 
    FD_SET(0, &allfd); 
    printf("*****Welcome to the Chatroom*****\n"); 

    while(1){ 
     modfd = allfd; 
     select(FD_SETSIZE, &modfd, NULL, NULL, NULL); 

     for(temp = 0; temp < FD_SETSIZE; temp++){ 
      if(FD_ISSET(temp, &modfd)){ 

       if(temp == 0){ 


        input = read(0, buf, MAX_BUF); 
        buf[input-1] = '\0'; //remove \n inserts termination 

        if((strncasecmp(buf, "create ", 7) == 0)) { 
         sendCmd(chat_socket, buf, 0); 
        } 
        else if((strncasecmp(buf, "join ", 5) == 0)) { 
         sendCmd(chat_socket, buf, 1); 
        } 
        else if((strncasecmp(buf, "delete ", 7)==0)){ 
         sendCmd(chat_socket, buf, 2); 
        } 
        else 
        { 
         printf("Enter a valid command: create <Room_name>, join <Room_name>, delete <Room_name>\n"); 
        } 
       } 
       else if(temp == chat_socket){ 
        input = read(temp, buf, MSG_SIZE); 
        memcpy(&temp_message, buf, sizeof(temp_message)); 

        if(temp_message.type == 10) { 
         printf("Created Chatroom\n"); 
        } 
        else if(temp_message.type == 11){ 
         connectChat(temp_message.length, host_name, chat_socket); 
          fflush(stdin); 
        } 
        else if(temp_message.type == 15) { 
         printf("Chatroom exits. Type join <Room_name> to join\n"); 
        } 
       } 
      } 
     } 
    } 

    close(chat_socket); 
    return 0; 
} 

は、私はそれが必要だっただけの場合には、コードの両方のセットを与えました。このプログラムは、複数のチャットルームを作成するように設計されています。あなたが警告の多くを見ることができます

CFLAGS=-Wall -g -O2 
CC=gcc 
LDFLAGS=-lpthread 

all: Server Client 

Server: Server.c 

Client: Client.c 

makeのコマンドを実行した後:

答えて

0

あなたがエラーアウトフィギュアへの道を探しているので、私はあなたがMakefile次使用することをお勧めします。いくつか:

Server.c: In function ‘createResponse’: 
Server.c:81:5: warning: ignoring return value of ‘write’, declared with attribute warn_unused_result [-Wunused-result] 
    write(chat_socket, temp_buff, MSG_SIZE); 
    ^

Server.c: In function ‘chat_room_main’: 
Server.c:237:25: warning: ‘chat_socket’ may be used uninitialized in this function [-Wmaybe-uninitialized] 
         close(chat_socket); 
         ^

Server.c: In function ‘main’: 
Server.c:319:36: warning: array subscript is above array bounds [-Warray-bounds] 
          msg_buf[19]= 0; 

Client.c: In function ‘connectChat’: 
Client.c:113:20: warning: passing argument 1 of ‘memset’ makes pointer from integer without a cast 
      memset(temp, 0, sizeof(buf)); 
        ^

これらの警告を修正してみてください。私はすべてそれらのを意味します。

+0

すべての警告を削除しました。 'server.c'の' chat_socketは設定されていますが使用されていません '。ただし、後でそのコードで使用されます。 – moneybags137

1

invalid argumentconnect()の文脈で意味EINVALエラーコードである:

無効な引数が検出された(例えば、address_lenは、アドレスファミリには有効ではありません、指定されたアドレスファミリーが無効です)。

お客様のクライアントコードにはconnect()が複数回コールされています(なぜですか?)が、失敗したコールはどれかを示していません。 connectChat()では少なくともsizeof(struct sockaddr)sizeof(struct sockaddr_in)、それ以上の場合はsizeof(sock)でなければなりません。main()のようになります。

connect()のいずれかが失敗した場合は、ソケットのリークはsocket()です。あなたはclose()にする必要があります。

また、gethostbyname()は廃止予定です。代わりにgetaddrinfo()を使用する必要があります。あなたはIPv4アドレスでしか動作しないIPv4ソケットを作成しています。アドレスバイトをsock変数にコピーする前に、gethostbyname()が実際にIPv4アドレス(host_name->h_addr_type == AF_INET)を返すかどうかをチェックしていません。少なくともgetaddrinfo()を指定すると、出力をIPv4アドレスだけに制限することができます。そのオプションはgethostbyname()ではありません。

+0

ありがとうございます。このエラーは主な機能にありました。わかりやすく私の投稿を編集しました。私はこれらの提案を適用し、私が得るものを見ます。 'getaddrinfo()'のパラメータに何を置くのですか? – moneybags137

+0

[ドキュメントを読む](http://man7.org/linux/man-pages/man3/getaddrinfo.3.html)。 –

関連する問題