c ++ system()挂起使用netcat连接到不同线程中的套接字
c++ system() hangs on using netcat to connect to socket in different thread
我在单独的线程上启动一个简单的套接字服务器,并尝试在主线程上使用 netcat
连接到它。这是代码:
#include <cstdlib>
#include <sys/socket.h>
#include <unistd.h>
#include <netinet/in.h>
#include <iostream>
#include <string>
#include <cstring>
using namespace std;
void* callback(void*);
bool isServerReady = false;
int main()
{
pthread_t thread;
int result = pthread_create(&thread, 0, callback, 0);
if (result != 0) {
cout << "[ERROR] Unable to create thread" << endl;
}
while (!isServerReady) {
}
int returnValue = system("echo TEST | netcat localhost 1234");
cout << "Return value: " << returnValue << endl;
return 0;
}
void* callback(void* threadId)
{
int serverSocketId = socket(AF_INET, SOCK_STREAM, 0);
if (serverSocketId == -1) {
cout << "[SERVER ERROR] Unable to create server socket." << endl;
return (void*)-1;
}
int serverPort = 1234;
struct sockaddr_in serverAddress;
serverAddress.sin_family = AF_INET;
serverAddress.sin_port = htons(serverPort);
serverAddress.sin_addr.s_addr = INADDR_ANY;
int bindReturn = bind(serverSocketId, (struct sockaddr*)&serverAddress, sizeof(serverAddress));
if (bindReturn == -1) {
cout << "[SERVER ERROR] Unable to bind server socket." << endl;
return (void*) -1;
}
isServerReady = true;
int waitQueueSize = 5;
listen(serverSocketId, waitQueueSize);
struct sockaddr_in clientAddress;
socklen_t clientAddressSize = sizeof(clientAddress);
int clientSocketId = accept(serverSocketId, (struct sockaddr*)&clientAddress, &clientAddressSize);
if (clientSocketId == -1) {
cout << "[SERVER ERROR] Unable to create client socket." << endl;
return (void*)-1;
}
char clientBuffer[256];
bzero(clientBuffer, 256);
int charsRead = read(clientSocketId, clientBuffer, 255);
if (charsRead == -1) {
cout << "[SERVER ERROR] Unable to read client socket." << endl;
return (void*)-1;
}
string serverMessage = "You wrote: ";
serverMessage.append(clientBuffer);
int charsWritten = write(clientSocketId, (char*)serverMessage.c_str(), (int)serverMessage.length());
if (charsWritten == -1) {
cout << "[SERVER ERRROR] Error writing to client socket." << endl;
return (void*)-1;
}
int closeReturn = close(serverSocketId);
if (closeReturn == -1) {
cout << "[SERVER ERROR] Error closing server socket." << endl;
return (void*)-1;
}
return (void*)0;
}
然而,system
函数从不 returns,使程序挂起:服务器的响应 "You wrote: TEST"
正确打印在控制台上,但之后程序就挂起,没有到达打印 return 值的行。如果我将相同的服务器代码提取到另一个程序中,启动它,并从命令行使用相同的 netcat
调用,我会得到相同的响应消息,然后 netcat
退出而不需要我做任何东西。
这是编译命令:
g++ -std=c++11 test.cpp -o test -lpthread && ./test
和编译器版本:
g++ (Ubuntu 4.8.4-2ubuntu1~14.04.1) 4.8.4
为什么您认为从 system()
内部调用时 netcat
不是 returning?
感谢@kfsone,问题只是我的服务器从未关闭客户端套接字,从而阻止客户端netcat
意识到服务器不再监听,并让它等待 no无限期的理由。解决这个问题:
// ...
string serverMessage = "You wrote: ";
serverMessage.append(clientBuffer);
int charsWritten = write(clientSocketId, (char*)serverMessage.c_str(), (int)serverMessage.length());
if (charsWritten == -1) {
cout << "[SERVER ERRROR] Error writing to client socket." << endl;
return (void*)-1;
}
// ADDED THIS:
int closeClientReturn = close(clientSocketId);
if (closeClientReturn == -1) {
cout << "[SERVER ERROR] Error closing client socket." << endl;
return (void*)-1;
}
int closeReturn = close(serverSocketId);
if (closeReturn == -1) {
cout << "[SERVER ERROR] Error closing server socket." << endl;
return (void*)-1;
}
return (void*)0;
我在单独的线程上启动一个简单的套接字服务器,并尝试在主线程上使用 netcat
连接到它。这是代码:
#include <cstdlib>
#include <sys/socket.h>
#include <unistd.h>
#include <netinet/in.h>
#include <iostream>
#include <string>
#include <cstring>
using namespace std;
void* callback(void*);
bool isServerReady = false;
int main()
{
pthread_t thread;
int result = pthread_create(&thread, 0, callback, 0);
if (result != 0) {
cout << "[ERROR] Unable to create thread" << endl;
}
while (!isServerReady) {
}
int returnValue = system("echo TEST | netcat localhost 1234");
cout << "Return value: " << returnValue << endl;
return 0;
}
void* callback(void* threadId)
{
int serverSocketId = socket(AF_INET, SOCK_STREAM, 0);
if (serverSocketId == -1) {
cout << "[SERVER ERROR] Unable to create server socket." << endl;
return (void*)-1;
}
int serverPort = 1234;
struct sockaddr_in serverAddress;
serverAddress.sin_family = AF_INET;
serverAddress.sin_port = htons(serverPort);
serverAddress.sin_addr.s_addr = INADDR_ANY;
int bindReturn = bind(serverSocketId, (struct sockaddr*)&serverAddress, sizeof(serverAddress));
if (bindReturn == -1) {
cout << "[SERVER ERROR] Unable to bind server socket." << endl;
return (void*) -1;
}
isServerReady = true;
int waitQueueSize = 5;
listen(serverSocketId, waitQueueSize);
struct sockaddr_in clientAddress;
socklen_t clientAddressSize = sizeof(clientAddress);
int clientSocketId = accept(serverSocketId, (struct sockaddr*)&clientAddress, &clientAddressSize);
if (clientSocketId == -1) {
cout << "[SERVER ERROR] Unable to create client socket." << endl;
return (void*)-1;
}
char clientBuffer[256];
bzero(clientBuffer, 256);
int charsRead = read(clientSocketId, clientBuffer, 255);
if (charsRead == -1) {
cout << "[SERVER ERROR] Unable to read client socket." << endl;
return (void*)-1;
}
string serverMessage = "You wrote: ";
serverMessage.append(clientBuffer);
int charsWritten = write(clientSocketId, (char*)serverMessage.c_str(), (int)serverMessage.length());
if (charsWritten == -1) {
cout << "[SERVER ERRROR] Error writing to client socket." << endl;
return (void*)-1;
}
int closeReturn = close(serverSocketId);
if (closeReturn == -1) {
cout << "[SERVER ERROR] Error closing server socket." << endl;
return (void*)-1;
}
return (void*)0;
}
然而,system
函数从不 returns,使程序挂起:服务器的响应 "You wrote: TEST"
正确打印在控制台上,但之后程序就挂起,没有到达打印 return 值的行。如果我将相同的服务器代码提取到另一个程序中,启动它,并从命令行使用相同的 netcat
调用,我会得到相同的响应消息,然后 netcat
退出而不需要我做任何东西。
这是编译命令:
g++ -std=c++11 test.cpp -o test -lpthread && ./test
和编译器版本:
g++ (Ubuntu 4.8.4-2ubuntu1~14.04.1) 4.8.4
为什么您认为从 system()
内部调用时 netcat
不是 returning?
感谢@kfsone,问题只是我的服务器从未关闭客户端套接字,从而阻止客户端netcat
意识到服务器不再监听,并让它等待 no无限期的理由。解决这个问题:
// ...
string serverMessage = "You wrote: ";
serverMessage.append(clientBuffer);
int charsWritten = write(clientSocketId, (char*)serverMessage.c_str(), (int)serverMessage.length());
if (charsWritten == -1) {
cout << "[SERVER ERRROR] Error writing to client socket." << endl;
return (void*)-1;
}
// ADDED THIS:
int closeClientReturn = close(clientSocketId);
if (closeClientReturn == -1) {
cout << "[SERVER ERROR] Error closing client socket." << endl;
return (void*)-1;
}
int closeReturn = close(serverSocketId);
if (closeReturn == -1) {
cout << "[SERVER ERROR] Error closing server socket." << endl;
return (void*)-1;
}
return (void*)0;