Come faccio a restituire un char da una funzione che utilizza Winsock per recv da presa?
-
29-09-2019 - |
Domanda
La mia applicazione si blocca quando provo a stampare il buffer. In caso contrario, funziona benissimo. Questo è il codice:
irc.h
class IRC
{
public:
void sockconnect(char * hName, int portNum);
void sockwrite(char* sendbuf);
char sockread(void);
bool connected;
private:
WSADATA wsaData;
SOCKET m_socket;
sockaddr_in clientService;
LPHOSTENT hostEntry;
};
irc.cc
char IRC::sockread(void)
{
int result;
char buffer[DEFAULT_BUFLEN];
result = recv(m_socket, buffer, DEFAULT_BUFLEN, 0);
if (result > 0) {
return *buffer;
}
else if (result == 0)
{
connected = false;
return *buffer;
}
else {
printf("recv failed with error: %d\n", WSAGetLastError());
return *buffer;
}
}
main.cc
IRC client;
while (client.connected == true) {
char buffer = client.sockread();
if (buffer == NULL)
break;
printf ("Buffer: %s\n",buffer);
}
Soluzione
Se si desidera stampare il primo utilizzo carattere
printf ("Buffer: %c\n",buffer);
Se si desidera stampare l'intero sockread poi dovrebbe restituire l'intero buffer, non il primo carattere. Per questo è necessario restituire l'indirizzo del primo elemento del buffer che in questo caso dovrebbe essere già allocato dinamicamente.
printf ("Buffer: %s\n",buffer);
Modifica Dopo averci pensato Penso che si desidera il secondo per il cambiamento che la funzione sockread()
nel seguente modo:
- cambiare il tipo di ritorno da
char
achar*
o meglioconst char*
-
char buffer[DEFAULT_BUFLEN];
achar* buffer = new char[DEFAULT_BUFLEN];
-
return *buffer
areturn buffer
Inoltre, in questo caso non dimenticate di cancellare il buffer di
const char* buffer = client.sockread(); //not char buffer as in your code
printf ("Buffer: %s\n",buffer);
delete [] buffer;
hth
Altri suggerimenti
È necessario utilizzare std :: string. Non è possibile tornare che buffer- è sullo stack locale. Anche se sei riuscito a tornare un puntatore reale ad esso invece di un singolo carattere, che è quello che avete fatto, allora sarebbe fuori del campo di applicazione e dei dati all'interno di esso non validi.
std :: string si prende cura di tutti questi problemi. Basta usarlo, ed è fatta. Hai anche altri problemi, come invalido ritorno di un buffer quando in realtà è fallito. Questo è ciò che le eccezioni sono per.
std::string IRC::sockread()
{
std::string s;
s.resize(DEFAULT_BUFLEN);
int result = recv(m_socket, &s[0], DEFAULT_BUFLEN, 0);
if (result > 0) {
return s;
} else if (result == 0) {
connected = false;
} else {
std::cout << "recv failed with error " << WSAGetLastError() << "\n";
}
throw std::runtime_error("Socket connection failed!");
}