多线程Socket编程服务器只从1个客户端线程获取消息

时间:2018-03-14 18:36:56

标签: c++ multithreading sockets pthreads client-server

对于基准测试任务,我正在创建具有相同套接字描述符的多个服务器工作者和具有单独连接的客户端工作者。

虽然客户端线程正在为每个线程发送相同消息的副本。服务器显示它只收到每个邮件的一个副本,而不是所有副本,通过所有客户端线程发送。

用于4个线程和2个消息{0,1},客户端输出

client 3Wrote 0
 client 1Wrote 1
 client 0Wrote 0
 client 1Wrote 0
 client 2Wrote 0
 client 3Wrote 1
 client 2Wrote 1

服务器输出的位置

Server 0 Received - 0
Server 2 Received - 1

为什么没有其他信息出现?或者它们实际上从未被客户发送过?

void *clientWorker(void *threadarg) {
    struct workDetails *thisWork;
    thisWork = (struct workDetails *) threadarg;
    int threadcount = thisWork->threadcount;
    int chunkSize = thisWork->chunkSize;
    char *serverIp = thisWork->serverIp;
    char *dataStore = thisWork->dataStore;

    int sockfd;
    struct sockaddr_in serv_addr;
    struct hostent *server;
    char *buffer = (char *) calloc(chunkSize, sizeof(char));
    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd < 0) error("ERROR opening client socket");
    server = gethostbyname(serverIp);
    if (server == NULL) error("Could not detect server by node name");

    bzero((char *) &serv_addr, sizeof(serv_addr));
    serv_addr.sin_family = AF_INET;
    bcopy((char *) server->h_addr,
          (char *) &serv_addr.sin_addr.s_addr,
          server->h_length);
    serv_addr.sin_port = htons(PORTNO);
    if (connect(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0)
        error("Server is not up.");
    long totalPackets = oneGBtoByte / (chunkSize * threadcount);
    long i;
    for (i = 0; i < totalPackets; ++i) {
        sprintf(buffer, "%ld", i);
        if (write(sockfd, buffer, chunkSize) < 0)
            error("ERROR writing to socket");
        else {
            lock_guard<mutex> guard(cout_mutex);
            cout << " client " << thisWork->threadid << "Wrote " << i << endl;
        }
    }
    cout << " client " << thisWork->threadid << "Exit";
    pthread_exit((void *) NULL);
}

void *serverWorker(void *threadarg) {
    struct workDetails *thisWork;
    thisWork = (struct workDetails *) threadarg;
    int threadcount = thisWork->threadcount;
    int chunkSize = thisWork->chunkSize;
    char *dataStore = thisWork->dataStore;
    int sockfd = thisWork->sockfd;
    char *buffer = new char[chunkSize];

    while (1) {

        if(read(sockfd, buffer, chunkSize) > 0){
            lock_guard<mutex> guard(cout_mutex);
            cout << "Server " << thisWork->threadid << " Received - " << buffer << endl;
        }
    }
    pthread_exit((void *) NULL);
}

1 个答案:

答案 0 :(得分:0)

问题是void *serverWorker(void *threadarg) { struct workDetails *thisWork; thisWork = (struct workDetails *) threadarg; int threadcount = thisWork->threadcount; int chunkSize = thisWork->chunkSize; char *dataStore = thisWork->dataStore; int sockfd = thisWork->sockfd; struct sockaddr_in cli_addr; // = thisWork->cli_addr; char *buffer = new char[chunkSize]; listen(sockfd, 5); socklen_t clilen = sizeof(cli_addr); sockfd = ::accept(sockfd, (struct sockaddr *) &cli_addr, &clilen); if (sockfd < 0) error("ERROR on accept"); while (1) { if (recv(sockfd, buffer, chunkSize, 0) > 0) { //lock_guard<mutex> guard(cout_mutex); //cout << "Server " << thisWork->threadid << " Received - " << buffer << endl; buffer[chunkSize] = NULL; strncat(dataStore, buffer, strlen(buffer)); if (strlen(dataStore) == oneGBtoByte) { cout << "Done - " << endl; storeInfile(created, dataStore); break; } } } //End delete[] buffer; pthread_exit((void *) NULL); } 在主线程中(在代码中不可见)。因此,虽然客户端尝试创建4个连接,但服务器只接受了一个连接。由于代码没有来回发送确认,因此输出没有显示此问题。 (没有乒乓球。理想情况下,大多数接收之后是发送确认,每次发送之后都是recv ack)。

当我将连接代码移动到线程工作者时。它按预期工作。

{{1}}

@ jeremy-friesner或@ gil-hamilton所说的是真的。但是这些问题在这里并不重要,因为我只对收到的总字节感兴趣,而不是谁收到了哪个块。