使用2个客户端在C中管理服务器中的多个线程

时间:2018-06-14 21:56:14

标签: c multithreading server client

我必须创建一个允许来自2个不同客户端的连接的服务器。所以我使用了线程。客户端和服务器通信良好但我有线程问题。基本上与第一个客户(选择咖啡类型的用户)我想将咖啡的价格发送到服务器。然后我想把这个价格从服务器发送到另一个客户端(然后我必须插入硬币和其他我必须实现的东西)。

当我运行服务器和第一个客户端时,服务器返回价格,这样就可以了。但是,当我尝试连接其他客户端时,程序返回错误。忽略第一部分并查看有线程的位置。我知道这里有一个错误,但我找不到它。

当我运行第一个客户端时:

iMac:bin $ ./client1 localhost

在服务器上我有这个:

Price received from client1: 0.500000 €

相反,当我运行第二个客户端时:

iMac:bin $ ./client2 localhost
Price received from server = 0

在服务器上我有这个:

read() failed: Undefined error: 0

从服务器收到的价格应该是= 0.500000€但我犯了错误。服务器再次输入prodSelected()但我希望当我运行client2时,服务器只能输入insertCoin()。我希望服务器在调用client1时只输入prodSelected()。所以在CLIENT1中我想选择咖啡,CLIENT1将咖啡的价格发送到SERVER,然后SERVER将咖啡的价格发送到CLIENT2。

非常感谢你的时间。原谅我的英语。

这是服务器:

#include"funzioni.h"
#include<stdio.h>
#include<string.h>    
#include<stdlib.h>    
#include<sys/socket.h>
#include<arpa/inet.h> 
#include<unistd.h>   
#include<pthread.h> 


void *prodSelected(void *);
void *insertCoin(void *);
float price= 0; //GLOBAL VARIABLE WHERE PRICE IS STORED

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

  //Create socket
  socket_desc = socket(AF_INET , SOCK_STREAM , 0);
  if (socket_desc == -1)
  {
    printf("Il socket non può essere creato");
  }
  puts("Socket creato");

  //Prepare the sockaddr_in structure
  server.sin_family = AF_INET;
  server.sin_addr.s_addr = INADDR_ANY;
  server.sin_port = htons( 3490 );


  //Bind
  if( bind(socket_desc,(struct sockaddr *)&server , sizeof(server)) < 0)
  {
    //print the error message
    perror("bind() fallito. Errore");
    return 1;
  }
  puts("bind() avvenuto con successo");

 //Listen
 listen(socket_desc , 3);

  //Accept and incoming connection
 puts("Attendendo connessioni in entrata...");
 c = sizeof(struct sockaddr_in);


  //Accept and incoming connection
  puts("Attendendo connessioni in entrata...");
  c = sizeof(struct sockaddr_in);



  pthread_t product;
  pthread_t coin;

  while( (client_sock = accept(socket_desc, (struct sockaddr *)&client, (socklen_t*)&c)) )
 {
    puts("Connection accettata");

    if( pthread_create( &product, NULL , &prodSelected, (void*) &client_sock) != 0){
        perror("Il thread non può essere creato");
        return 1;
    }





    if( pthread_create( &coin , NULL , &insertCoin, (void*) &client_sock) != 0){
        perror("Il thread non può essere creato");
        return 1;
    }



   if(pthread_join( coin , NULL)!=0){
            fprintf(stderr, "pthread_join() Errore");
            exit(0);
    }
    if(pthread_join( product , NULL)!=0){
         fprintf(stderr, "pthread_join() Errore");
         exit(0);
    }


    puts("Handler assegnato");
  }

  if (client_sock < 0){
     perror("accept() fallito");
     return 1;
  }

 return 0;
}


pthread_mutex_t client1=PTHREAD_MUTEX_INITIALIZER;


/*
 * Handle client connection
 * */

//Receive price of the product from Client1
void *prodSelected(void *socket_desc){

 int sock = *(int*)socket_desc;
 int received_int = 0;
 int return_status;
 pthread_mutex_lock(&client1);
 return_status = read(sock, &received_int, sizeof(received_int)); //
 if (return_status > 0) {
   fprintf(stdout, "Product selected = %d\n", ntohl(received_int));
 }
else {
    perror("read() failed ");
    exit(1);
 }

 //these are some function included in my header file

 stampaPrezzo(ntohl(received_int)); 
 prezzo = comunicaPrezzo(ntohl(received_int));
 pthread_mutex_unlock(&client1);
 printf("Price received from client1: %f €\n",price );
 return 0;
}

 // Send price from Server to Client2.
 void *insertCoin(void *arg){

 int sock = *(int*)arg;
 int number_to_send = price;
 int converted_number = htonl(number_to_send);
 write(sock, &converted_number, sizeof(converted_number));


}

1 个答案:

答案 0 :(得分:1)

也许您应该详细阅读有关accept()的文档。

DESCRIPTION
       The  accept()  system  call  is used with connection-based socket types
       (SOCK_STREAM,  SOCK_SEQPACKET).   It  extracts  the  first   connection
       request  on  the queue of pending connections for the listening socket,
       sockfd, creates a new connected socket, and returns a new file descrip‐
       tor  referring  to that socket.  The newly created socket is not in the
       listening state.  The original socket  sockfd  is  unaffected  by  this
       call.

accept()返回一个引用客户端 - 服务器连接的新fd。

存储库可以解决您的问题:https://github.com/yorickdewid/Chat-Server