基本的には、マルチスレッドクライアント間のメッセージを、C++のソケットを使用して単一のスレッドコーディネーターに交換することです。クライアントはファイルにアクセスするための許可を要求し、コーディネーターはそれらをキューに入れ、一度に1つずつ許可します。私はこれが最善の解決策ではないと思うが、クライアントがすべてのメッセージをそこに送るように、コーディネーター用のポート2000にソケットを作成することを考えた。各クライアントは識別子(ポート2001,2002,2003 ...)を持つソケットを作成し、コーディネーターは必要なときにいつでもこれらのポートを介してそれらに応答することができます。私が抱えている問題は、クライアントがコーディネーターによって付与された最初のものであっても、自分のソケットのaccept()関数に固執していることです。ここでは以下の私のコードは、(coutの "私がここには、" クライアントに示されることはありません、それが立ち往生しています場所それはだ - 53行)です:単一のサーバーへの複数のクライアントソケットC++
coordinator.cpp:
#include <iostream>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
using namespace std;
int main (int argc, char** argv) {
const int REQUEST = 1;
const int GRANT = 2;
const int RELEASE = 3;
const char* portno = "2000";
int queue[128] = {0};
int last = 0;
int socket_receive, newsocket_receive, socket_send, port_send;
string msg, msg_send;
char buffer[256];
memset(buffer, '|', 256);
struct addrinfo hints, *res;
struct addrinfo hints_send, *res_send;
struct sockaddr_in client_address;
bzero((char*) &hints, sizeof(hints));
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = AI_PASSIVE;
getaddrinfo(NULL,portno,&hints,&res);
socket_receive = socket(res->ai_family,res->ai_socktype,res->ai_protocol);
bind(socket_receive, res->ai_addr, res->ai_addrlen);
listen(socket_receive,5);
socklen_t client_lenght = sizeof(client_address);
while (1){
newsocket_receive = accept(socket_receive,(struct sockaddr*)&client_address,&client_lenght);
int n = recv(newsocket_receive,buffer,sizeof(buffer),0);
msg.append(buffer, buffer+n);
copy(buffer+n, buffer+256, buffer);
char subarray[n];
memset(subarray, '|', n);
copy(subarray, subarray+n, buffer+256-n);
int elems[2];
int i = 0;
while (i < sizeof(msg)-1){
if (msg[i] == ':'){
break;
}
i++;
}
if (i < 4){
const char* char_msg0 = msg.substr(0,i).c_str();
const char* char_msg1 = msg.substr(i+1,sizeof(msg)).c_str();
elems[0] = atoi(char_msg0);
elems[1] = atoi(char_msg1);
if (elems[1] == REQUEST){
if (last == 0){
port_send = 2000 + elems[0];
string str_port_send = to_string(port_send);
char const* char_port_send = str_port_send.c_str();
getaddrinfo("localhost",char_port_send,&hints_send,&res_send);
socket_send = socket(res_send->ai_family,res_send->ai_socktype,res_send->ai_protocol);
connect(socket_send,res_send->ai_addr,res_send->ai_addrlen);
msg_send = to_string(GRANT);
cout << "Coordinator: sending GRANT message to consumer " << elems[0] << endl;
send(socket_send, msg_send.data(),msg_send.size(),0);
close(socket_send);
queue[last] = elems[0];
last++;
}
else {
queue[last] = elems[0];
last++;
}
}
else if (elems[1] == RELEASE){
//SHIFT QUEUE
last--;
}
msg = "";
}
}
close(socket_receive);
return 0;
}
client.cpp:
#include <iostream>
#include <pthread.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <algorithm>
using namespace std;
void *request (void *arg){
const int REQUEST = 1;
const int GRANT = 2;
const int RELEASE = 3;
int id = *((int *) arg);
string msg_send, msg_receive;
const char* portno = "2000";
const char* port_receive = to_string(2000+id).c_str();
int socket_send, socket_receive, newsocket_receive;
char buffer [256];
struct addrinfo hints, *res;
struct addrinfo hints_receive, *res_receive;
struct sockaddr_in client_address;
bzero((char*) &hints, sizeof(hints));
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = AI_PASSIVE;
getaddrinfo("localhost",portno,&hints,&res);
socket_send = socket(res->ai_family,res->ai_socktype,res->ai_protocol);
connect(socket_send,res->ai_addr,res->ai_addrlen);
msg_send = to_string(id) + ":" + to_string(REQUEST);
cout << "Client: sending REQUEST message to coordinator." << endl;
send(socket_send,msg_send.data(),msg_send.size(),0);
close(socket_send);
getaddrinfo(NULL,port_receive,&hints_receive,&res_receive);
socket_receive = socket(res_receive->ai_family,res_receive->ai_socktype,res_receive->ai_protocol);
bind(socket_receive, res_receive->ai_addr, res_receive->ai_addrlen);
listen(socket_receive,5);
socklen_t client_lenght = sizeof(client_address);
newsocket_receive = accept(socket_receive,(struct sockaddr*)&client_address,&client_lenght);
cout << "I'm here" << endl;
int n = recv(newsocket_receive,buffer,sizeof(buffer),0);
msg_receive.append(buffer, buffer+n);
cout << msg_receive << endl;
copy(buffer+n, buffer+256, buffer);
char subarray[n];
memset(subarray, '|', n);
copy(subarray, subarray+n, buffer+256-n);
close(socket_receive);
}
int main (int argc, char** argv) {
int n_threads = atoi(argv[1]);
pthread_t threads[n_threads];
for (long i=1; i<=n_threads; i++){
int *arg = (int *) malloc(sizeof(*arg));
*arg = i;
pthread_create(&threads[i], NULL, request, arg);
}
pthread_exit(NULL);
return 0;
}
私はそれについて考えましたが、後で使用したいソケットをどのようにして保存できますか?キュー内の各ソケットをどのように識別するのですか? –
また、聞くことは問題ではありませんでしたが、気づいていただきありがとうございます。私はそれをループから外しました。 –
@EduardoDeMelloCastanhoそれは単なるデータ構造の問題です。確かに、あなたはデータ構造を選択して設計することができますか? – EJP