C++ Socket服务端/客户端程序:输入Exit无法触发终止逻辑问题
Hey there, let's dig into why your Exit command isn't working—and fix a few other potential headaches while we're at it!
The Root Cause: Comparing C-Strings Wrong
The big mistake here is how you're checking for the "Exit" command. In C/C++, when you write strBuf == "Exit", you're not comparing the actual text of the strings—you're comparing the memory addresses of the two char pointers. The string literal "Exit" lives in a read-only section of memory, while strBuf is on the stack, so this condition will never be true, no matter what you type.
To compare the content of C-style strings correctly, you need to use the strcmp() function from <string.h>. It returns 0 when the two strings are identical.
Other Hidden Issues in Your Code
While we're fixing the main problem, let's address a few other things that could cause trouble later:
scanf("%s", strBuf)stops reading as soon as it hits a space or newline—so if you type a message with spaces, only the first word gets sent to clients.- No thread exit logic: Even if you fixed the string comparison, the loop would keep running after sending the termination message.
- Buffer overflow risk:
scanfdoesn't check if input exceeds your 100000-byte buffer, which could lead to memory corruption.
Fixed Code Example
#include <string.h> #include <stdio.h> #include <unistd.h> // Assuming nClient and nFDList are properly defined elsewhere int nClient; int nFDList[]; void *admin_handler(void *ptr) { char strBuf[100000]; const char strExitMsg[] = "Server: terminated."; const char strExitCmd[] = "Exit"; while (1) { // Use fgets instead of scanf to read full lines (including spaces) if (fgets(strBuf, sizeof(strBuf), stdin) == NULL) { // Handle read error or EOF break; } // Remove the trailing newline added by fgets size_t msgLen = strlen(strBuf); if (msgLen > 0 && strBuf[msgLen - 1] == '\n') { strBuf[msgLen - 1] = '\0'; msgLen--; } // Correct string comparison with strcmp if (strcmp(strBuf, strExitCmd) == 0) { // Send termination message to all clients for (int i = 0; i < nClient; i++) { write(nFDList[i], strExitMsg, strlen(strExitMsg) + 1); close(nFDList[i]); // Close the client connection } nClient = 0; // Reset client count break; // Exit the loop to end the thread cleanly } else { // Forward the message to all clients for (int i = 0; i < nClient; i++) { write(nFDList[i], strBuf, msgLen + 1); } } } return NULL; }
Key Fixes Explained
strcmpfor string comparison: This checks the actual characters in the strings, not their memory addresses.fgetsinstead ofscanf: Reads entire lines, preserves spaces, and prevents buffer overflow by usingsizeof(strBuf)to limit input length.- Trim trailing newline:
fgetsincludes the newline character from input—we remove it so clients don't get extra line breaks. - Proper thread exit: After sending termination messages, we close client connections, reset the client count, and break out of the loop to end the thread cleanly.
Bonus Tips for C++ Development
Since you're working in C++, consider using std::string instead of C-style char arrays. It's safer, supports direct == comparison for content, and handles memory management automatically. Also, make sure to add thread safety for nClient and nFDList (like a mutex) if clients can connect/disconnect while this thread is running—otherwise you might hit array out-of-bounds errors.
内容的提问来源于stack exchange,提问作者Andrew

