Ich schreibe ein TCP-Kommunikationsskript in C++, um zwischen meinem Computer und einem Aldebaran Nao-Roboter zu kommunizieren.TCP-Verbindung mit ungültigen Verbindungsblöcken Port
Im Allgemeinen funktioniert mein Skript. Das Problem, das ich habe, ist jedoch, dass wenn ich vom Client Verbindung anrufe (wenn die Server-Anwendung geschlossen oder die Ethernet-Verbindung entfernt wird), bekomme ich einen Fehler, dass die Operation läuft.
Sobald jedoch die Server-Anwendung neu gestartet/Ethernet-Kabel wieder verbunden ist, kann ich noch nicht verbinden, um eine Verbindung erfolgreich wiederherzustellen. Ich bekomme immer noch einen Fehler, dass die Operation ausgeführt wird.
Wenn mein Client feststellt, dass eine Verbindung nicht hergestellt werden kann, wird der Socket-Deskriptor vor dem erneuten Versuch einer Verbindung geschlossen. Hier ist mein Code für die Verbindung auf der Client-Seite:
Wenn es weitere Informationen gibt, die nützlich wären, würde ich gerne zur Verfügung stellen. Dieses Projekt ist relativ groß, daher wollte ich hier nicht zu viele irrelevante Informationen hinzufügen.
TCPStream* TCPConnector::connect(const char* serverIP, int port, int timeoutSec)
{
if (timeoutSec == 0)
{
return connect(serverIP, port);
}
struct sockaddr_in address;
// Store all zeros for address struct.
memset(&address, 0, sizeof(address));
// Configure address struct.
address.sin_family = AF_INET;
address.sin_port = htons(port); // Convert from host to TCP network byte order.
inet_pton(PF_INET, serverIP, &(address.sin_addr)); // Convert IP address to network byte order.
// Create a socket. The socket signature is as follows: socket(int domain, int type, int protocol)
int sd = socket(AF_INET, SOCK_STREAM, 0);
int optval = 1;
if (setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof optval) == -1)
{
std::cout << "failed to set socket option" << std::endl;
}
// Set socket to be non-blocking.
int arg;
arg = fcntl(sd, F_GETFL, NULL);
arg |= O_NONBLOCK;
fcntl(sd, F_SETFL, arg);
// Connect with time limit.
fd_set set;
FD_ZERO(&set); // Clear the set.
FD_SET(sd, &set); // Add our file descriptor to the set.
struct timeval timeout;
timeout.tv_sec = timeoutSec;
timeout.tv_usec = 0;
// If the connect call returns 0, then the connection was established. Otherwise,
// check if the three-way handshake is underway.
if (::connect(sd, (struct sockaddr *)&address, sizeof(address)) < 0)
{
// If the handshake is underway.
if (errno == EINPROGRESS)
{
std::cout << "handshake in progress" << std::endl;
// Designate timeout period.
int ret = select(sd + 1, NULL, &set, NULL, &timeout);
std::cout << "return value from select : " << ret << std::endl;
// Check if timeout or an error occurred.
if (ret <= 0)
{
return NULL;
}
else
{
// Check if select returned 1 due to an error.
int valopt;
socklen_t len = sizeof(int);
getsockopt(sd, SOL_SOCKET, SO_ERROR, (void*)(&valopt), &len);
if (valopt)
{
char * errorMessage = strerror(errno); // get string message from errn
std::string msg (errorMessage);
std::cout << msg << std::endl;
return NULL;
}
}
}
else
{
return NULL;
}
}
// Return socket to blocking mode
arg = fcntl(sd, F_GETFL, NULL);
arg &= (~O_NONBLOCK);
fcntl(sd, F_SETFL, arg);
// Create stream object.
return new TCPStream(sd, &address);
}
Es blockiert den Port nicht. Ihr Code geht in eine Endlosschleife. – EJP
@EJP Können Sie erklären, was die Endlosschleife verursacht? – Austin