2016-12-12 18 views
0

©チャットプログラムを作成しようとしています.Serverはmsgを取得し、他のすべてのクライアントを送信します。は、すべてのクライアントにメッセージを送信しました。

クライアントからメッセージを受け取るのに問題はありません。しかし、来たときにSendToAll機能が動作しません。

おかげであなたの助け

サーバ

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


    #define PORT 7777 
    #define SIZE 1024 


    struct clients{ 
    struct sockaddr_in clientAddr; 
    struct clients *next; 
}; 




struct clients *AddClient(struct sockaddr_in new_ClientAddr,struct clients *head) 
{ 

    struct clients *temp = head; 
    puts("burda2"); 
    int a = 1; 
    if(head == NULL) 
    { 
     temp = (struct clients *)malloc(sizeof(struct clients)); 
     temp->clientAddr = new_ClientAddr; 
     temp->next = NULL; 
    } 
    else 
    { 
     while(temp != NULL) 
     { 
     if(temp->clientAddr.sin_addr.s_addr == new_ClientAddr.sin_addr.s_addr) 
     { 
     a = 0; 
     break; 
     } 
      temp = temp->next; 
     } 
     if(a == 1) 
     { 
      temp->next = (struct clients *)malloc(sizeof(struct clients)); 
      temp->next->clientAddr = new_ClientAddr; 
      temp = temp->next; 
      temp->next = NULL; 
     } 
     else{ 
      puts("Its already save"); 
     } 
    } 
    return head; 
} 
    // --- End of Function AddClient() --- 

void SendToAll(char msg[1023], struct sockaddr_in repliedClient, struct clients *head) 
{ 
    struct clients *temp = head; 
    int clients_socket; 
    int byte; 
    clients_socket = socket(AF_INET, SOCK_STREAM, 0); 
     if(clients_socket == -1) 
      perror("Error On Socket(SendToAll)"); 
    while(temp != NULL) 
    { 

     if(repliedClient.sin_addr.s_addr != temp->clientAddr.sin_addr.s_addr)//Dont send msg who to replied 
     { 
      if(connect(clients_socket, (struct sockaddr *)&temp->clientAddr, 
               sizeof(struct sockaddr)) == -1) 
      { 
       perror("Error on Connect(SendToAll)"); 


      byte = send(clients_socket, msg, strlen(msg), 0); 
      printf("%s message send",msg); 

      if(byte == -1) 
       perror("Error on Send(SendToAll"); 
      else if(byte == 0) 
       printf("Connection've been closed"); 

      temp = temp->next; 
      } 
     } 
    } 

} 
// --- End of Function SendToAll() --- 



int main(int argc, char *argv[]) 
{ 
    struct clients *head = NULL; 
    int socket_fd, temp_fd; 
    struct sockaddr_in serverAddr,new_clientAddr; 
    int structSize,byte; 
    char text[1023]; 

    // Creating socket 
    socket_fd = socket(AF_INET, SOCK_STREAM, 0); 
    if(socket_fd == -1) 
     perror("Error on Soket"); 

    // Editting Server socket 
    serverAddr.sin_family = AF_INET; 
    serverAddr.sin_port = htons(PORT); 
    serverAddr.sin_addr.s_addr = INADDR_ANY; 
    memset(&(serverAddr.sin_zero), '\0', 8); 

    // Bind 
    if(bind(socket_fd, (struct sockaddr *)&serverAddr, sizeof(struct sockaddr)) == -1) 
     perror("Error on Bind"); 

    // Start listen the port 
    if(listen(socket_fd, 20) == -1 ) 
     perror("Error on Listen"); 

    structSize = sizeof(new_clientAddr); 

    while(1) 
    { 
     puts(" "); 
     // Accept 
     temp_fd = accept(socket_fd , (struct sockaddr *)&new_clientAddr, &structSize); 
     if(temp_fd == -1) 
      perror("Error on Accept"); 
     // Recv 
     byte = recv(temp_fd, &text, SIZE-1, 0); 
     if(byte == -1) 
      perror("Error on Recv"); 
     else if(byte == 0) 
      printf("Connection is close\n"); 
     printf("%s", text); 
     //Add to list 
     head = AddClient(new_clientAddr, head); 
     //Send message to other clients 
     SendToAll(text, new_clientAddr, head); 

     close(temp_fd);  
    } 


    close(socket_fd); 


    return (EXIT_SUCCESS); 
} 

クライアント

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

//#define ServerIP "35.162.226.229" 
#define ServerIP "127.0.0.1" 
#define ServerPort 7777 
#define SIZE 1024 





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

    int socket_fd; 
    struct sockaddr_in serverAddr; 
    char text[SIZE],msg[SIZE-20], name[20]text temizlendi,get_msg[1024]; 
    int byte; 
    // Nick 
    printf("Please enter your nick"); 
    scanf("%s",name); 
    //Create Socket 
    socket_fd = socket(AF_INET, SOCK_STREAM, 0); 
    if(socket_fd == -1) 
     perror("Error on Socket"); 

    serverAddr.sin_family = AF_INET; 
    serverAddr.sin_port = htons(ServerPort); 
    serverAddr.sin_addr.s_addr =inet_addr(ServerIP); 
    memset(&(serverAddr.sin_zero), '\0', 8); 

    // Connect to server 
    if(connect(socket_fd, (struct sockaddr *)&serverAddr, sizeof(struct sockaddr)) == -1) 
     perror("Error on Connect"); 
    puts("Connected"); 
    while(1) 
    { 
     //Get message 
     printf(">>>"); scanf("%s",msg); 
     //Edit message 
     strcpy(text, name); 
     strcat(text, " : "); 
     strcat(text, msg); 
     //Send message 
     byte = send(socket_fd, text, strlen(text), 0); 
     if(byte == -1) 
      perror("Error on Send"); 
     else if(byte == 0) 
      printf("Connection've been closed"); 
     //Get reply to other users 

     recv(socket_fd, &get_msg, SIZE-1, 0); 
     printf("Getting message %s", get_msg); 
    } 
    //Close socket 
    close(socket_fd); 



    return (EXIT_SUCCESS); 
} 
+1

なぜ 'SendToAll()'に 'connect()'の呼び出しが含まれていますか?すでにサーバーに接続しているクライアントにメッセージを送信しようとしていませんか? –

+0

私はソケットに関する非常に経験がないので、これはこのようなものでなければならないと思います。間違っていますか? –

+0

はい、間違っています。ソケットインタフェースは、永続的な(閉じたまで)*双方向*通信チャネルを提供します。クライアント 'connect()'とサーバ 'accept()'は接続を確立し、その後、それぞれの端は単に適切にソケットに書き込み、ソケットから読み込みます。完了したら、各端はソケットを 'close()'しなければなりません。 –

答えて

0

ない限りまで(あなたはそれが双方向であるSOCK_STREAM接続を開いて、それがすべての時間を開いているときあなたがそれを終わらせるか、タイムアウトしたか、それとも何かのように)。

接続されているすべてのクライアントにメッセージを送信する場合は、グローバルクライアント構造を反復するループを作成します。 struct clients{ struct sockaddr_in clientAddr; struct clients *next; }; 各クライアントIDに対してsend()操作を実行します。

connect()が(サーバーからクライアントエンドで実行している場合)もう一方の側で成功するには、ソケットリスナーが必要です。つまりlisten()によって行われます。

つまりサーバー側からはできません。 また、チャットサーバーを作成するために、サーバーコードでI/O多重化と呼ばれる処理を実行する必要があります。あなたが書いたコードはそれを実行しません。つまり、あなたは呼び出しをブロックしているaccept()を使用しています。

サーバが

  1. が接続を受け入れ、
  2. は、接続されたクライアントからメッセージを受信し、他のすべてのクライアントにブロードキャスト接続を追跡実行される2つの主要な課題があります。

これらの2つの操作は、互いにブロックされていない必要があります。したがって、これらのタスクを並行して実行するにはスレッド/複数のプロセスも必要になります。

希望します。

+0

ありがとうhcjivani! 私は自分の考えの欠点を理解しました:) –

関連する問題