TCP 连接被拒绝 C++
TCP connection refused c++
我在连接到我的 TCP 服务器套接字时遇到问题。我以前用过它,但在添加线程后我只用 g++ main.cpp
编译它时遇到问题,不得不使用更高版本,之后它就无法连接。线程真的不应该干扰 TCP 连接的执行。似乎可能是缺少编译器版本或标志可能是问题所在,但我不确定。
我禁用了防火墙,也尝试过打开防火墙并接受连接,但没有成功。
我的客户端返回错误 "Connection refused"。
Wireshark 数据包仅显示两个数据包,这是有道理的,因为握手尚未完成。
我用g++ main.cpp -std=gnu++2a -pthread
编译服务器,用./a.out
编译运行,用g++ testClientSocket.cpp -o testClient -std=gnu++2a -pthread
编译客户端,用[=18]编译客户端运行 =]
服务器在另一个文件中调用,代码为:
int main(){
ServerSocket ss = ServerSocket(4000, "127.0.0.1");
}
客户端在另一个文件中调用:
int main(){
SocketClient s = SocketClient(4000, "127.0.0.1");
}
服务器代码:
#include <sys/socket.h>
#include <stdlib.h>
#include <iostream>
#include <string>
#include <unistd.h>
#include <stdio.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <mutex>
#include <thread>
#include "./Worker.cpp"
#include <vector>
using namespace std;
class ServerSocket{
public:
ServerSocket(int PORT, string ip_address){
Worker worker_threads(4);
worker_threads.start(); // Create a worker loop
mutex worker_lock; // Lock for avoiding race conditions.
int serverFd = socket(AF_INET, SOCK_STREAM, 0); // File descriptor, -1 on error
if(serverFd == -1) cerr << "Socket creation failed" << endl;
bool runThreads = true;
//Datastructure for storing address
struct sockaddr_in server;
int addressLength = sizeof(server);
// reuse SOCKET AND ADDRESS/PORT
int opt = 0;
if(setsockopt(serverFd, SOL_SOCKET, SO_REUSEADDR , &opt, sizeof(opt))) perror("setsockopt failed");
//Bind socket to port/ip
bind(serverFd, (sockaddr*)&server, sizeof(server));
//Initializes the address datastructure with appropriate addresses.
server.sin_family = AF_INET;
server.sin_addr.s_addr = INADDR_ANY;
server.sin_port = htons(PORT);
//Listen for incoming connections
int listenStatus = listen(serverFd, SOMAXCONN); //SOMAXCONN max queue length acc. to os.
if(listenStatus == -1) perror("listen error");
//Serves as event loop for server at this time. Will maybe change this later
while(runThreads) {
sockaddr_in client;
socklen_t clientSize = sizeof(client);
int new_socket = accept(serverFd, (struct sockaddr *)&client,(socklen_t*)&clientSize);
if (new_socket == -1) perror("accept failed");
else cout << "Connection established" << endl;
cout << "after accept" << endl;
connections.push_back(new_socket); //Push filedescriptor to connection to vector.
threads.emplace_back([this, new_socket, &worker_threads, &worker_lock]{
lock_guard<mutex> lock(worker_lock); // lock for code block
//worker_threads.post() // POST WORK TO WORKER
});
}
}
void broadcastBallot(string message){
//May need to message from string to bytes or something else for efficiency and logistics.
//Connections only have filedescriptors
//Send message to connected clients
for(auto &con : connections){
send(con, message.c_str() , strlen(message.c_str()) , 0 );
}
}
void setCastedVotes(){
//Readbuffer
char readBuffer[1024] = {0};
//May need a buffer for each connection, or use the same for all connections.
for(auto &con : connections){
//Read incoming stream to bufferArray
int readStatus = read(con , readBuffer, 1024);
cout << readStatus << endl;
//Print out from readBuffer
printf("%s\n", readBuffer );
//TODO: SHOULD SET AN ARRAY OR SOMETHING
}
}
private:
vector<int> connections;
vector<thread> threads;
};
客户代码:
#include <stdio.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string>
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <netinet/in.h>
#include <iostream>
#include <string>
#include <cstring>
using namespace std;
class SocketClient{
public:
SocketClient(int PORT, string ip_addr){
//Create socket
int sock_fd = socket(AF_INET, SOCK_STREAM, 0);
if(sock_fd == -1) cerr << "Socket creation failed" << endl;
//For storing information about address and port etc.
struct sockaddr_in address;
//Initializing address etc.
address.sin_family = AF_INET;
address.sin_port = htons(PORT);
inet_pton(AF_INET, ip_addr.c_str(), &address.sin_addr);
//Connect to serversocket
int connection = connect(sock_fd, (sockaddr*)&address, sizeof(address));
if(connection == -1) {
perror("Cannot connect\n");
}
string helloMsg = "hello";
int sendResult = send(sock_fd, helloMsg.c_str(), helloMsg.size()+1,0);
char readBuffer[1024];
while(true){
int readResult = recv(sock_fd, readBuffer, 1024,0);
printf("%s\n", readBuffer );
}
}
private:
};
这里的一个错误是服务器地址在调用bind
之后被初始化。所以它的内容在那个调用中是未定义的(因此取决于编译器、OS 和月相)。很有可能就是这个问题。
此外,SO_REUSEADDR
在代码中设置为零(即FALSE);这可能不是本意,可能会导致快速重启时出现问题。
我在连接到我的 TCP 服务器套接字时遇到问题。我以前用过它,但在添加线程后我只用 g++ main.cpp
编译它时遇到问题,不得不使用更高版本,之后它就无法连接。线程真的不应该干扰 TCP 连接的执行。似乎可能是缺少编译器版本或标志可能是问题所在,但我不确定。
我禁用了防火墙,也尝试过打开防火墙并接受连接,但没有成功。
我的客户端返回错误 "Connection refused"。
Wireshark 数据包仅显示两个数据包,这是有道理的,因为握手尚未完成。
我用g++ main.cpp -std=gnu++2a -pthread
编译服务器,用./a.out
编译运行,用g++ testClientSocket.cpp -o testClient -std=gnu++2a -pthread
编译客户端,用[=18]编译客户端运行 =]
服务器在另一个文件中调用,代码为:
int main(){
ServerSocket ss = ServerSocket(4000, "127.0.0.1");
}
客户端在另一个文件中调用:
int main(){
SocketClient s = SocketClient(4000, "127.0.0.1");
}
服务器代码:
#include <sys/socket.h>
#include <stdlib.h>
#include <iostream>
#include <string>
#include <unistd.h>
#include <stdio.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <mutex>
#include <thread>
#include "./Worker.cpp"
#include <vector>
using namespace std;
class ServerSocket{
public:
ServerSocket(int PORT, string ip_address){
Worker worker_threads(4);
worker_threads.start(); // Create a worker loop
mutex worker_lock; // Lock for avoiding race conditions.
int serverFd = socket(AF_INET, SOCK_STREAM, 0); // File descriptor, -1 on error
if(serverFd == -1) cerr << "Socket creation failed" << endl;
bool runThreads = true;
//Datastructure for storing address
struct sockaddr_in server;
int addressLength = sizeof(server);
// reuse SOCKET AND ADDRESS/PORT
int opt = 0;
if(setsockopt(serverFd, SOL_SOCKET, SO_REUSEADDR , &opt, sizeof(opt))) perror("setsockopt failed");
//Bind socket to port/ip
bind(serverFd, (sockaddr*)&server, sizeof(server));
//Initializes the address datastructure with appropriate addresses.
server.sin_family = AF_INET;
server.sin_addr.s_addr = INADDR_ANY;
server.sin_port = htons(PORT);
//Listen for incoming connections
int listenStatus = listen(serverFd, SOMAXCONN); //SOMAXCONN max queue length acc. to os.
if(listenStatus == -1) perror("listen error");
//Serves as event loop for server at this time. Will maybe change this later
while(runThreads) {
sockaddr_in client;
socklen_t clientSize = sizeof(client);
int new_socket = accept(serverFd, (struct sockaddr *)&client,(socklen_t*)&clientSize);
if (new_socket == -1) perror("accept failed");
else cout << "Connection established" << endl;
cout << "after accept" << endl;
connections.push_back(new_socket); //Push filedescriptor to connection to vector.
threads.emplace_back([this, new_socket, &worker_threads, &worker_lock]{
lock_guard<mutex> lock(worker_lock); // lock for code block
//worker_threads.post() // POST WORK TO WORKER
});
}
}
void broadcastBallot(string message){
//May need to message from string to bytes or something else for efficiency and logistics.
//Connections only have filedescriptors
//Send message to connected clients
for(auto &con : connections){
send(con, message.c_str() , strlen(message.c_str()) , 0 );
}
}
void setCastedVotes(){
//Readbuffer
char readBuffer[1024] = {0};
//May need a buffer for each connection, or use the same for all connections.
for(auto &con : connections){
//Read incoming stream to bufferArray
int readStatus = read(con , readBuffer, 1024);
cout << readStatus << endl;
//Print out from readBuffer
printf("%s\n", readBuffer );
//TODO: SHOULD SET AN ARRAY OR SOMETHING
}
}
private:
vector<int> connections;
vector<thread> threads;
};
客户代码:
#include <stdio.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string>
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <netinet/in.h>
#include <iostream>
#include <string>
#include <cstring>
using namespace std;
class SocketClient{
public:
SocketClient(int PORT, string ip_addr){
//Create socket
int sock_fd = socket(AF_INET, SOCK_STREAM, 0);
if(sock_fd == -1) cerr << "Socket creation failed" << endl;
//For storing information about address and port etc.
struct sockaddr_in address;
//Initializing address etc.
address.sin_family = AF_INET;
address.sin_port = htons(PORT);
inet_pton(AF_INET, ip_addr.c_str(), &address.sin_addr);
//Connect to serversocket
int connection = connect(sock_fd, (sockaddr*)&address, sizeof(address));
if(connection == -1) {
perror("Cannot connect\n");
}
string helloMsg = "hello";
int sendResult = send(sock_fd, helloMsg.c_str(), helloMsg.size()+1,0);
char readBuffer[1024];
while(true){
int readResult = recv(sock_fd, readBuffer, 1024,0);
printf("%s\n", readBuffer );
}
}
private:
};
这里的一个错误是服务器地址在调用bind
之后被初始化。所以它的内容在那个调用中是未定义的(因此取决于编译器、OS 和月相)。很有可能就是这个问题。
此外,SO_REUSEADDR
在代码中设置为零(即FALSE);这可能不是本意,可能会导致快速重启时出现问题。