我必须创建一个允许来自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));
}
答案 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