2017-04-23 3 views
-1

Hallo, ich muss Nachrichten aus dem Socket als String erhalten, habe ich Probleme mit dem recv() erfordert eine Lücke *, aber ich brauche es in Zeichenfolge Ich bin ziemlich neu zu C++ jede Hilfe würde sehr geschätzt werden. Der Code, den ich verwende, ist unten aufgeführt.Problem mit Recv-Socket-Typ Argument

#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

Lesen Sie in eine Byte-Array und konvertieren Sie das in eine Zeichenfolge, – EJP

Antwort

1

std :: string buffer.c_str() ist eine Konstante. So funktioniert es nur auf diese Weise hier beschrieben: C++ Read From Socket into std::string

+0

Vielen Dank für Ihre Hilfe, ich dachte, es gab eine andere Möglichkeit, den Puffer durch etwas wie lesen statt zu behandeln recv() Ich hatte es zuvor als char Puffer [sizehere] und es funktionierte gut. Nochmals vielen Dank –

+0

Nun, ich würde dies nicht auf diese Weise tun, denn aus Sicherheitsgründen ist es gefährlich anzunehmen, dass die Daten immer eine Zeichenfolge sind. – 0x0C4

+0

verstanden. Dies ist eher eine HW-Zuweisung als eine Produktionstyp-Anwendung, aber ich schätze das Feedback –