2017-04-23 18 views
-1

こんにちはソケットからメッセージを文字列として受け取る必要があります。recv()に問題があります。void *が必要ですが、文字列で必要です。大変感謝します。私が使用しているコードは以下の通りです。recvソケット型引数の問題

#include "server.h" 

using namespace std; 

//Actually allocate clients 
vector<Client> Server::chatClients; 

Server::Server() { 

    //Initialize the mutex 
    Thread::initMut(); 
    int yes = 1; 
    //https://www.cs.cmu.edu/afs/cs/academic/class/15213-f99/www/class26/tcpserver.c 
    serverSocket = socket(AF_INET, SOCK_STREAM, 0); 
    memset(&serverAddr, 0, sizeof(sockaddr_in)); 
    serverAddr.sin_family = AF_INET; 
    serverAddr.sin_addr.s_addr = INADDR_ANY; 
    serverAddr.sin_port = htons(PORT); 

    //check if socket was closed last time; 
    setsockopt(serverSocket, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)); 

    if(::bind(serverSocket, (struct sockaddr *) &serverAddr, sizeof(sockaddr_in)) < 0) 
     cerr << "Failed during the binding process"; 
     listen(serverSocket, 5); 
} 

void Server::receiveAndSend() { 

    Client *client; 
    Thread *thread; 

    socklen_t cliSize = sizeof(sockaddr_in); 
    //run forever 
    while(true) { 

     client = new Client(); 
     thread = new Thread(); 

     client->socket = accept(serverSocket, (struct sockaddr *) &clientAddr, &cliSize); 

     if(client->socket < 0) { 
      cerr << "Error while accepting"; 
     } 
     else { 
      thread->generate((void *) Server::ClientHandler, client); 
     } 
    } 
} 

//todo use one lock, and change everything to a string. 

void *Server::ClientHandler(void *args) { 

    //client Pointer 
    Client *client = (Client *) args; 
    string buffer; 
    string message; 
    int index; 
    int n; 

    //Add client to the clients vector 
    Thread::lockMut((const string) client->clientName); 

    //set the id of the client by getting the largest index of the vector 
    client->setClientId(Server::chatClients.size()); 
    client->setClientName(buffer); 
    cout << "Adding client with id: " << client->clientId << endl; 
    Server::chatClients.push_back(*client); 

    Thread::unlockMut((const string) client->clientName); 

    while(1) { 
//  memset(buffer, 0, sizeof buffer); 
     n = recv(client->socket, buffer.c_str(), sizeof buffer, 0); 

     //Client disconnected? 
     if(n == 0) { 
      cout << "Client " << client->clientName << " diconnected" << endl; 
      close(client->socket); 

      //Remove client in Static clients <vector> (Critical section!) 
      Thread::lockMut((const char *) client->clientName); 

      index = Server::getClientIndex(client); 
      cout << "earse user with index: " << index << "andid is: " 
       << Server::chatClients[index].clientId << endl; 
      Server::chatClients.erase(Server::chatClients.begin() + index); 

      Thread::unlockMut((const char *) client->clientName); 

      break; 
     } 
     else if(n < 0) { 
      cerr << "receive error: " << client->clientName << endl; 
     } 
     else { 
      //Message is here now broadcast. 
      cout << message.c_str() << " " << client->clientName << " " << buffer; 
      cout << "Will send to all: " << message << endl; 
      Server::PublicBroadcast(message); 
     } 
    } 

    //End thread 
    return NULL; 
} 

void Server::PublicBroadcast(string message) { 
    int size; 

    //Acquire the lock 
    Thread::lockMut("'PublicBroadcast()'"); 

    for(size_t i=0; i<chatClients.size(); i++) { 

//  ssize_t send(int, const void *, size_t, int) __DARWIN_ALIAS_C(send); 
     cout << message << endl ; 
     size = send(Server::chatClients[i].socket, message.c_str(), message.length(),0); 
     cout << size << " sent bytes." << endl; 
    } 

    //Release the lock 
    Thread::unlockMut("'PublicBroadcast()'"); 
} 

void Server::ListClients() { 
    for(size_t i=0; i<chatClients.size(); i++) { 
     cout << chatClients.at(i).clientName << endl; 
    } 
} 

/* 
    Should be called when vector<Client> clients is locked! 
*/ 

int Server::getClientIndex(Client *client) { 
    for(size_t i=0; i<chatClients.size(); i++) { 
     if((Server::chatClients[i].clientId) == client->clientId) return (int) i; 
    } 
    cerr << "clientId not found." << endl; 
    return -1; 
} 
+0

バイト配列に読み込み、それを文字列に変換します – EJP

答えて

1

std :: string buffer.c_str()は定数です。したがって、ここで説明されているこの方法でのみ動作します:C++ Read From Socket into std::string

+0

助けていただきありがとうございます。バッファの代わりに読み込みのような方法でバッファを処理する方法がありましたrecv()私はそれ以前にcharバッファ[sizehere]としてそれを持っていました。もう一度ありがとう –

+0

セキュリティを将来的に考えると、データは常に文字列であると仮定するのは危険なので、私はそうしないでしょう。 – 0x0C4

+0

が理解される。これは、生産型のアプリケーションよりもハードウェア割り当ての方が多いですが、私はフィードバックに感謝します –