У меня проблемы с подключением к сокету TCP-сервера. Раньше у меня это работало, но после добавления потоков у меня были проблемы с компиляцией с g++ main.cpp
, и мне пришлось использовать более высокую версию, и после этого она не подключалась. Потоки действительно не должны связываться с выполнением соединения TCP. И кажется, что это может быть версия или флаг компилятора, который отсутствует, что может быть проблемой, но я не уверен.
У меня отключен брандмауэр, а также пробовал с включенным брандмауэром и принятием соединений , но безуспешно.
Мой клиент возвращает перрор "Отказано в соединении".
Пакеты Wireshark показывают только два пакета, что имеет смысл, поскольку квитирование не завершено.
Я компилирую сервер с g++ main.cpp -std=gnu++2a -pthread
, запускаю с ./a.out
, компилирую клиент с g++ testClientSocket.cpp -o testClient -std=gnu++2a -pthread
и запускаю с ./testClient
Сервер вызывается в другом файле с кодом:
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:
};