I need to receive a HTTP request from my browser, when I run localhost:8228 it works fine, I receive the header in the buffer and am able to write it to the console and even echo send it back to the browser. But when I try reading a request from a actual webpage, buffer is empty, it prints nothing.
I have a simple main that looks like this:
int main (int argc, char *argv[]) {
char buffer[1024*1024] = {0};
int port_number = 8228;
if (argc == 1)
std::cout << "Using default port number, 8228." << std::endl;
else if (argc == 3) {
port_number = atoi(argv[2]);
} else {
std::cout << "::Error::" << std::endl;
std::cout << "Wrong number of arguments." << std::endl;
exit[0];
}
AppSocket app;
app.Start((int)port_number);
app.AcceptCall();
int request_size = app.ReceiveRequest(buffer, sizeof(buffer));
return 0;
}
My AppSocket functions would be:
void AppSocket::Start(int port) {
// Create a socket
listening_fd = socket(AF_INET, SOCK_STREAM, 0);
if (listening_fd == -1) {
std::cerr << "Could not create a socket." << std::endl;
exit(-1);
}
app_hint.sin_family = AF_INET;
app_hint.sin_port = htons(port);
inet_pton(AF_INET, "127.0.0.1", &app_hint.sin_addr);
if (bind(listening_fd, (sockaddr*)&app_hint, sizeof(app_hint))< 0) {
std::cerr << "Cannot bind to IP/port." << std::endl;
exit(-2);
}
std::cout << "Socket has been bound." << std::endl;
if (listen(listening_fd, SOMAXCONN) == -1) {
std::cerr << "Cannot listen." << std::endl;
exit(-3);
}
std::cout << "Listening to port " << port << std::endl;
std::cout << "Your socket is: " << listening_fd << std::endl;
}
void AppSocket::AcceptCall() {
client_size = sizeof(client_addr);
client_fd =
accept(listening_fd, (sockaddr *)&client_addr, &client_size);
if (client_fd < 0) {
std::cerr << "Error connecting to client." << std::endl;
exit(-4);
}
std::cout << inet_ntoa(client_addr.sin_addr)
<< " connected to port "
<< ntohs(client_addr.sin_port) << std::endl;
close(listening_fd);
}
int AppSocket::ReceiveRequest(char *buffer, int max) {
std::cout << "Client is: " << client_fd << std::endl;
memset(buffer, 0, buff_size); //clear buffer
int n = recv(client_fd, buffer, buff_size, 0);
if (n < 0)
std::cerr << "A connection issue has occured." << std::endl;
if (n == 0)
std::cout << "Client disconected." << std::endl;
std::cout << "recv return " << n << std::endl;
std::cout << buffer << std::endl;
return n;
}
When I run and access a webpage I get this:
Using default port number, 8228.
Socket has been bound.
Listening to port 8228
Your socket is: 3
127.0.0.1 connected to port 37522
Client is: 4
recv return 3
None of the questions I've read seem to work for me...
edit: sorry one of the lines in the main code wasn't copied.
How can I receive repeatedly? A while loop? I tried that and just kept receiving nothing.
The code works, what was happening is that the firefox proxy settings were wrong, when I ran localhosts it worked fine because it was actually working as the server due to the port it was using but when trying to access a "real" website it didn't. After configuring it correctly it did just what it's supposed to do.
Related
I'm making simple chatting program with c++.
The structure of the server program like this,
■ MAIN
check client connection
if client connected -> make sub thread to connection with client
■ SUB THREAD
recv message from client
when client disconnected, delete User(custom class) Object from userList(std::vector)
The problem is, when I execute one client, sending message to server works well.
And execute second client(it means two clients have connection with server at the same time), second client send message is fine, but when send message to server with first client, first client disconnected from server.
I tried:
When I add dump User Object to userList(0), it works well. (why?) => I think something wrong with initialize vector, but i'm not sure.
I did't use mutex yet, but I think this problem is not cause by not using mutex.
this is my codes:
Server.cpp
#include "Server.h"
void communicateClient(std::vector<User*>* userList, User* user) {
bool clientConnected = true;
char recvMessage[Constants::NETWORK_MESSAGE_SIZE] = { 0, };
while (clientConnected) {
if (recv(user->getUserSocket(), recvMessage, sizeof(recvMessage), 0) == -1) {
std::cout
<< Constants::LOG_NETWORK
<< std::to_string(user->getUserSockAddrIn().sin_addr.S_un.S_un_b.s_b1) << "."
<< std::to_string(user->getUserSockAddrIn().sin_addr.S_un.S_un_b.s_b2) << "."
<< std::to_string(user->getUserSockAddrIn().sin_addr.S_un.S_un_b.s_b3) << "."
<< std::to_string(user->getUserSockAddrIn().sin_addr.S_un.S_un_b.s_b4) << ":"
<< std::to_string(user->getUserSockAddrIn().sin_port) << " client disconnected" << std::endl;
clientConnected = false;
}
else {
std::cout
<< Constants::LOG_NETWORK
<< std::to_string(user->getUserSockAddrIn().sin_addr.S_un.S_un_b.s_b1) << "."
<< std::to_string(user->getUserSockAddrIn().sin_addr.S_un.S_un_b.s_b2) << "."
<< std::to_string(user->getUserSockAddrIn().sin_addr.S_un.S_un_b.s_b3) << "."
<< std::to_string(user->getUserSockAddrIn().sin_addr.S_un.S_un_b.s_b4) << ":"
<< std::to_string(user->getUserSockAddrIn().sin_port) << " send message: "
<< recvMessage << std::endl;
}
}
closesocket(user->getUserSocket());
std::vector<User*>::iterator userIterator;
for (userIterator = userList->begin(); userIterator != userList->end(); userIterator++) {
if ((*userIterator)->getUserId() == user->getUserId()) {
delete(*userIterator);
userList->erase(userIterator);
break;
}
}
std::cout << "client count: " << userList->size() << std::endl;
}
int main() {
WSADATA wsaData;
SOCKET serverSocket;
SOCKADDR_IN serverAddr;
std::cout << Constants::LOG_START << "Chatting server started" << std::endl;
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
std::cout << Constants::LOG_ERROR << "Error WSAStartup()" << std::endl;
return -1;
}
serverSocket = socket(AF_INET, SOCK_STREAM, Constants::PROTOCOL);
if (serverSocket == INVALID_SOCKET) {
std::cout << Constants::LOG_ERROR << "Error socket()" << std::endl;
}
memset(&serverAddr, 0, sizeof(serverAddr));
serverAddr.sin_family = AF_INET;
inet_pton(AF_INET, Constants::SERVER_IP.c_str(), &serverAddr.sin_addr);
serverAddr.sin_port = htons(Constants::SERVER_PORT);
if (bind(serverSocket, (SOCKADDR*)&serverAddr, sizeof(serverAddr)) == SOCKET_ERROR) {
std::cout << Constants::LOG_ERROR << "Error bind()" << std::endl;
}
if (listen(serverSocket, Constants::CLIENT_CONNECT_LIMIT) == SOCKET_ERROR) {
std::cout << Constants::LOG_ERROR << "Error listen()" << std::endl;
}
std::vector<User*> userList;
std::vector<std::thread*> clientConnectionThread;
serverState = true;
while (serverState) {
std::cout << Constants::LOG_WAIT << "waiting client connection..." << std::endl;
SOCKADDR_IN clientSockAddrIn;
SOCKET clientSocket;
int clientSockAddrInSize = sizeof(clientSockAddrIn);
clientSocket = accept(serverSocket, (SOCKADDR*)&clientSockAddrIn, &clientSockAddrInSize);
if (clientSocket == SOCKET_ERROR) {
std::cout << Constants::LOG_ERROR << "Error accept()" << std::endl;
}
else {
std::cout
<< Constants::LOG_SUCCESS
<< std::to_string(clientSockAddrIn.sin_addr.S_un.S_un_b.s_b1) << "."
<< std::to_string(clientSockAddrIn.sin_addr.S_un.S_un_b.s_b2) << "."
<< std::to_string(clientSockAddrIn.sin_addr.S_un.S_un_b.s_b3) << "."
<< std::to_string(clientSockAddrIn.sin_addr.S_un.S_un_b.s_b4) << ":"
<< std::to_string(clientSockAddrIn.sin_port) << " client connected" << std::endl;
User* user = new User;
user->setUserSocket(clientSocket);
user->setUserSockAddrIn(clientSockAddrIn);
userList.push_back(user);
clientConnectionThread.push_back(new std::thread(communicateClient, &userList, std::ref(userList.back())));
std::cout << "client count: " << userList.size() << std::endl;
}
}
std::vector<std::thread>::iterator threadIterator;
for (threadIterator = clientConnectionThread.begin(); threadIterator != clientConnectionThread.end(); threadIterator++) {
(*threadIterator).join();
}
WSACleanup();
return 0;
}
Client.cpp
#include "Client.h"
int main() {
WSADATA wsaData;
SOCKET serverSocket;
SOCKADDR_IN serverAddr;
std::cout << "client start" << std::endl;
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
std::cout << "Failed WSAStartup()" << std::endl;
}
serverSocket = socket(PROTOCOL_TYPE, SOCK_STREAM, IPPROTO_TCP);
if (serverSocket == INVALID_SOCKET) {
std::cout << "Failed socket()" << std::endl;
}
memset(&serverAddr, 0, sizeof(serverAddr));
serverAddr.sin_family = PROTOCOL_TYPE;
inet_pton(AF_INET, SERVER_IP.c_str(), &serverAddr.sin_addr);
serverAddr.sin_port = htons(SERVER_PORT);
std::cout << "connecting to server..." << std::endl;
while (true) {
if (connect(serverSocket, (SOCKADDR*)&serverAddr, sizeof(serverAddr)) == SOCKET_ERROR) {
std::cout << "Fail to connect server: retry in 2 seconds..." << std::endl;
Sleep(1000);
}
else {
break;
}
}
std::string sendMessage;
char recvMessage[256] = { 0, };
printf("send message to server...\n");
while (true) {
std::cout << "Write Message: ";
std::getline(std::cin, sendMessage);
send(serverSocket, sendMessage.c_str(), sendMessage.length() + 1, 0);
}
closesocket(serverSocket);
WSACleanup();
system("pause");
return 0;
}
I have a server in a raspberry pi, and want to allow multithreading. The server is working. The client is in windows.
I believe I need to send the socket id through the pthread_create, but haven't found how. Is there anything else I need to send?
What is the best way to do it?
I've searched the internet, stackoverflow included, and tryed some resolutions, but they didn't work.
const int PORT = 12000;
TCPServer tcp;
pthread_t my_thread[MAXCLIENTQUEUE];
int clientID = 0;
int main()
{
tcp.setup(PORT);
int clientQueueSize = 0, threadJoin = 0;
void *res;
do {
socklen_t sosize = sizeof(tcp.clientAddress);
//realizar o accept
tcp.newsockfd[clientQueueSize] = accept(tcp.sockfd, (struct sockaddr*) & tcp.clientAddress, &sosize);
if (tcp.newsockfd[clientQueueSize] == -1)
{
cout << "Error accepting -> " << tcp.newsockfd[clientQueueSize] << endl;
tcp.detach();
}
cout << ">- accept: " << strerror(errno) << " / codigo: " << tcp.newsockfd[clientQueueSize] << " - Endereco: " << inet_ntoa(tcp.clientAddress.sin_addr) << endl;
clientID++;
cout << ">>> client accepted" << " | Client ID: " << clientID << endl;
// criar threads
int ret = pthread_create(&my_thread[clientQueueSize], NULL, messenger, &tcp.newsockfd[clientQueueSize]);
cout << ">- pthread: " << strerror(errno) << " / codigo: " << ret << endl;
if (ret != 0) {
cout << "Error: pthread_create() failed\n" << "thread_n " << my_thread[clientQueueSize] << endl;
exit(EXIT_FAILURE);
}
cout << "thread n " << my_thread[clientQueueSize] << endl;
clientQueueSize++;
}
while (clientQueueSize < MAXCLIENTQUEUE);
pthread_exit(NULL);
return 0;
}
The server accepts multiple connections but only sends messages to the first client, the others connected successfully, but never receive messages.
I want for the server to be able to send messages to all the clients.
You have to create threads for all sockets.
Or, use Windows-depended async select methods.
P.S. Forget pthreads and use the standard std::thread.
map<SOCKET,std::string> clients;
void newclient(SOCKET x)
{
for(;;)
{
int r = recv(x,...);
if (r == 0 || r == -1)
break;
}
// remove it from clients, ensure proper synchronization
}
void server()
{
SOCKET x = socket(...);
bind(x,...);
listen(x,...);
for(;;)
{
auto s = accept(x,...);
if (s == INVALID_SOCKET)
break;
// save to a map, for example, after ensuring sync with a mutex and a lock guard
m[s] = "some_id";
std::thread t(newclient,s);
s.detach();
}
}
int main() //
{
// WSAStartup and other init
std::thread t(server);
t.detach();
// Message Loop or other GUI
}
So I have been developing something for multi-computer use (I'm working on a botnet in order to prove for a school project that computers can be easily hacked as a project for GITA) and I can't seem to make a connection with the server and client. The client can connect via 127.0.0.1, however, when attempted to connect via IPv4 or the external ip (can be found www.whatsmyip.org) it doesn't seem to work. So I have tried everything, even disabling my firewall but nothing.
I'm wondering if I happened to make a mistake in my code?
Client:
#include "client.h"
Client* Client::clientptr;
int Client::Initalize(const char* add)
{
char ownPth[MAX_PATH];
// When NULL is passed to GetModuleHandle, the handle of the exe itself is returned
HMODULE hModule = GetModuleHandle(NULL);
if (hModule != NULL)
{
// Use GetModuleFileName() with module handle to get the path
GetModuleFileName(hModule, ownPth, (sizeof(ownPth)));
std::cout << ownPth << std::endl;
}
else
{
std::cout << "Module handle is NULL" << std::endl;
}
WSAData wsaData;
WORD DllVersion = MAKEWORD(2, 1);
if (WSAStartup(DllVersion, &wsaData) != 0)
{
std::cout << "ERROR: WINSOCK INVALID!" << std::endl;
exit(0);
}
std::cout << "Setting SOCKADDR_IN addr..." << std::endl;
addrlen = sizeof(addr);
addr.sin_addr.s_addr = inet_addr(add);
addr.sin_port = htons(4403);
addr.sin_family = AF_INET;
connection = socket(AF_INET, SOCK_STREAM, NULL);
while (true)
{
std::cout << "Attempting connection..." << std::endl;
if (connect(connection, (SOCKADDR*)&addr, addrlen) > 0 || connect == 0)
{
std::cout << "Connection established!" << std::endl;
break;
}
std::cout << "Error: Failed to connect! Retrying... " << std::endl;
Sleep(1000);
}
clientptr = this;
return 0;
}
int Client::Run()
{
std::cout << std::endl << "Running..." << std::endl;
while (true)
{
Sleep(10);
}
return 0;
}
Server:
#include "server.h"
Server* Server::serverptr; //Serverptr is necessary so the static ClientHandler method can access the server instance/functions.
int Server::Initalize()
{
std::cout << "Setting crash handler..." << std::endl;
std::cout << "Looking at winsock dll version..." << std::endl;
WSADATA wsaData;
WORD DllVersion = MAKEWORD(2, 1);
if (WSAStartup(DllVersion, &wsaData) != 0)
{
MessageBoxA(NULL, "Winsock startup failed", "Error", MB_OK | MB_ICONERROR);
exit(1);
}
std::cout << "Creating listening socket..." << std::endl;
addrlen = sizeof(addr);
addr.sin_addr.s_addr = htonl(INADDR_ANY);
addr.sin_port = htons(4403);
addr.sin_family = AF_INET;
std::cout << "The socket data addr "
<< "{"
<< "addr.sin_addr.s_addr = " << addr.sin_addr.s_addr
<< ", addr.sin_port = " << addr.sin_port
<< ", addr.sin_family = " << addr.sin_family
<< "}" << std::endl;
sListen = socket(AF_INET, SOCK_STREAM, NULL); //Create socket to listen for new connections
if (bind(sListen, (SOCKADDR*)&addr, sizeof(addr)) == SOCKET_ERROR) //Bind the address to the socket, if we fail to bind the address..
{
std::string ErrorMsg = "Failed to bind the address to our listening socket. Winsock Error:" + std::to_string(WSAGetLastError());
MessageBoxA(NULL, ErrorMsg.c_str(), "Error", MB_OK | MB_ICONERROR);
exit(1);
}
if (listen(sListen, SOMAXCONN) == SOCKET_ERROR) //Places sListen socket in a state in which it is listening for an incoming connection. Note:SOMAXCONN = Socket Oustanding Max connections, if we fail to listen on listening socket...
{
std::string ErrorMsg = "Failed to listen on listening socket. Winsock Error:" + std::to_string(WSAGetLastError());
MessageBoxA(NULL, ErrorMsg.c_str(), "Error", MB_OK | MB_ICONERROR);
exit(1);
}
std::cout << "Finalizing..." << std::endl;
output = false;
currClient = 0;
std::cout << "Setting serverptr..." << std::endl;
serverptr = this;
std::cout << "Creating Threads..." << std::endl;
serverptr->Listening = false;
CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)Listen, NULL, NULL, NULL); //Create thread that will manage all outgoing packets
while (serverptr->Listening == false);
std::cout << "Done Initalizing!" << std::endl << std::endl;
return 0;
}
int Server::Run()
{
std::cout << "Running server...";
serverptr->Listening = true;
while (true)
{
std::string userinput;
int inputInt;
HANDLE hConsoe = GetStdHandle(STD_OUTPUT_HANDLE);
while (true)
{
std::cout << std::endl << "] ";
std::getline(std::cin, userinput);
serverptr->HandleInput(userinput);
}
}
return 0;
}
void Server::Listen()
{
if (serverptr->output)
std::cout << "Listener socket running..." << std::endl;
serverptr->Listening = true;
while (true)
{
if (serverptr->Listening == true)
{
SOCKET newConnection //the connection for the socket
= accept(serverptr->sListen, (SOCKADDR*)&serverptr->addr, &serverptr->addrlen); //Accept a new connection
if (newConnection == 0)
{
if (serverptr->output)
std::cout << "FAILED TO ACCEPT THE CLIENTS CONNECTION!" << std::endl;
}
else
{
if (serverptr->output)
{
std::cout << "A connection has been made [" << inet_ntoa(serverptr->addr.sin_addr) << "]!" << std::endl;
std::cout << "Creating Client(" << newConnection << ")..." << std::endl;
}
Client newClient(newConnection, serverptr->addr);
int connectionId = serverptr->clients.size();
serverptr->clients.push_back(newClient);
CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)RecvClient, NULL, NULL, NULL); //Create thread that will manage all incomming packets
int index = serverptr->clients.size() - 1;
while (!serverptr->clients[index].Listening);
if (serverptr->output)
std::cout << "Client success [" << (index + 1) << "]!" << std::endl;
}
}
}
return;
}
void Server::RecvClient()
{
int index = serverptr->clients.size() - 1;
char data[1600];
if (serverptr->output)
std::cout << "Listening for client[" << (index + 1) << "]..." << std::endl;
serverptr->clients[index].Listening = true;
while (true)
{
recv(serverptr->clients[index]._socket, data, sizeof(data), 0);
if (serverptr->output)
std::cout << "Data Recieved from client[" << (index + 1) << "]!" << std::endl;
if ((int)data[0] < 0)
{
if (serverptr->output)
std::cout << "Client [" << (index + 1) << "] is disconnecting with the current code {" << (int)data[0] << "}..." << std::endl;
serverptr->DisconnectClient(index);
break;
}
}
if (serverptr->output)
std::cout << "No longer listening for client[" << (index + 1) << "]!" << std::endl;
}
void Server::HandleInput(std::string string)
{
std::string sHandle = string;
std::istringstream iss(string);
std::vector<std::string> sTokens((std::istream_iterator<std::string>(iss)),
std::istream_iterator<std::string>());
if (sHandle == "cls")
{
system("cls");
return;
}
if (sHandle == "list")
{
int index = serverptr->clients.size() - 1;
std::cout << "Total Clients: " << serverptr->clients.size() << std::endl;
for (int i = 0; i < serverptr->clients.size(); i++)
{
std::cout << (char)195 << (char)196 << " Client [" << i + 1 << "] {" << serverptr->clients[i]._socket << ", " << inet_ntoa(serverptr->clients[i]._address.sin_addr) << "}" << std::endl;
}
return;
}
if (sHandle == "data")
{
std::cout << "Toggling data output..." << std::endl;
serverptr->output = true;
return;
}
if (sTokens[0] == "broadcast")
{
int change = 0;
std::cout << "Toggling client: ";
if (sTokens.size() > 1)
{
std::stringstream strings(sTokens[1]);
strings >> change;
if (change > serverptr->clients.size())
{
change = serverptr->clients.size();
}
}
if (change > 0) std::cout << change << std::endl;
else std::cout << "All" << std::endl;
serverptr->currClient = change;
return;
}
std::cout << "Error: Unknown command!" << std::endl;
return;
}
void Server::DisconnectClient(int id)
{
if (serverptr->output)
std::cout << "void Server::DisconnectClient(" << id << ")..." << std::endl;
closesocket(serverptr->clients[id]._socket);
serverptr->clients.erase(serverptr->clients.begin() + (id));
return;
}
Client::Client(SOCKET socket, SOCKADDR_IN address)
{
this->_address = address;
this->_socket = socket;
this->Listening = false;
}
i'm working on an simple network server example. It should accept TCP- and UDP-requests and answer with an asctime string. UDP is working whithout any issues. TCP makes some problems on windows. I work on linux for myself but have to make this little example running on windows. The university PCs are running windows. So for your information i tried crosscompiling and even compiling on the system itself.
The actual problem is on linux is everything working fine. The following code is my attempt to realise a non-blocking TCP-listener which responds with the asctime-string when it gets a request (user defined port not only 13):
void Server::tcpListen(int port)
{
socklen_t size = sizeof(sockaddr);
sockaddr_in remoteHost;
mAddress.sin_port = htons(port);
int r = bind(mTcpSocket, (sockaddr*) &mAddress, sizeof(sockaddr));
if(r < 0)
{
cerr << "Couldn't bind port. (" << std::strerror(errno) << " " << errno << ")" << endl;
#ifdef WIN32
cerr << "WSA Error: " << WSAGetLastError() << endl;
#endif
mTcpServerRunning = false;
return;
}
cout << "TCP:\tListen on port " << port << '\n';
r = listen(mTcpSocket, 5);
if(r < 0)
{
cerr << "Couldn't listen. " << std::strerror(errno) << " " << endl;
mTcpServerRunning = false;
return;
}
time_t t;
struct tm *timeinfo;
std::string timeMsg;
mTcpServerRunning = true;
while(mTcpServerRunning)
{
int cSock = accept(mTcpSocket, (sockaddr*) &remoteHost, &size);
if(cSock < 0)
{
continue;
}
char buf[5];
r = recv(cSock, buf, sizeof(buf), 0);
if(r > 0)
{
time(&t);
timeinfo = localtime(&t);
timeMsg = asctime(timeinfo);
r = send(cSock, (char*) timeMsg.c_str(), timeMsg.length(), 0);
if(r < 0)
{
cerr << "send error: " << errno << endl;
exit(EXIT_FAILURE);
}
uint8_t ip[4];
memcpy(ip, &remoteHost.sin_addr.s_addr, sizeof(ip));
cout << "-----------------------------------------------------" << endl;
cout << "Request-Type: TCP" << " / " << timeMsg.c_str() << endl;
cout << "IP: "
<< (int) ip[0]
<< "." << (int) ip[1]
<< "." << (int) ip[2]
<< "." << (int) ip[3]
<< " / Port (Client): " << remoteHost.sin_port << endl;
cout << "-----------------------------------------------------" << endl;
}
}
close(mTcpSocket);
#ifdef WIN32
WSACleanup();
#endif
mTcpServerRunning = false;
}
To debug the connection i used wireshark which told me the connection attempt isn't unanswered. The initialisation with the three-way-handshake works (SYN -> SYN, ACK -> ACK). Even the request (empty string) is working. (PSH, ACK -> ACK) but the server doesn't respond with the time-string. I opened the ports and even disabled the firewall completely.
Is there anything wrong with the WSASocket usage? Blocking TCP-receiving doesn't work either. I have thought about the loop repeating before answering and then overwriting the cSock descriptor returned from accept.
EDIT: Initialization of the sockets:
#ifdef WIN32
WSADATA wsaData;
if (WSAStartup (MAKEWORD(1, 1), &wsaData) != 0) {
fprintf (stderr, "WSAStartup(): Couldn't initialize Winsock.\n");
exit (EXIT_FAILURE);
}
#endif
mTcpSocket = socket(AF_INET, SOCK_STREAM, 0);
mUdpSocket = socket(AF_INET, SOCK_DGRAM, 0);
#ifdef _WIN32
unsigned long nonblocking = 1;
// if(ioctlsocket(mTcpSocket,FIONBIO, &nonblocking))
// std::cout << "Couldn't set TCP-Socket to nonblocking mode! ("
// << std::strerror(errno) << ")" << endl;
if(ioctlsocket(mUdpSocket, FIONBIO, &nonblocking))
std::cerr << "Couldn't set UDP-Socket to nonblocking mode! ("
<< std::strerror(errno) << ")" << endl;
#else
int tcpFlags = fcntl(mTcpSocket, F_GETFL, 0);
int udpFlags = fcntl(mUdpSocket, F_GETFL, 0);
if(fcntl(mTcpSocket, F_SETFL, tcpFlags | O_NONBLOCK))
std::cout << "Couldn't set TCP-Socket to nonblocking mode! ("
<< std::strerror(errno) << ")" << endl;
if(fcntl(mUdpSocket, F_SETFL, udpFlags | O_NONBLOCK))
std::cerr << "Couldn't set UDP-Socket to nonblocking mode! ("
<< std::strerror(errno) << ")" << endl;
#endif
I'm trying my hands at network programming for the first time, implementing a small IRC bot using the SFML network functionality.
The connection gets established, but from there on I can't do much else. Trying to receive any data from the server yields nothing, until I get the "Ping timeout" message after a few seconds.
Removing all or some of the receive() calls in the loginOnIRC function doesn't do any good.
Trying to connect via telnet with the exact same messages works. Here I get a PING message right after sending my NICK message.
Am I missing something?
My code is as follows
#include <iostream>
#include <string>
#include <SFML/Network.hpp>
#define ARRAY_LEN(x) (sizeof(x)/sizeof(*x))
void receive(sf::TcpSocket* sck)
{
char rcvData[100];
memset(rcvData, 0, ARRAY_LEN(rcvData));
std::size_t received;
if (sck->receive(rcvData, ARRAY_LEN(rcvData), received) != sf::Socket::Done)
{
std::cout << "oops" << std::endl;
}
std::cout << "Received " << received << " bytes" << std::endl;
std::cout << rcvData << std::endl;
}
int establishConnection(sf::TcpSocket* sck)
{
sf::Socket::Status status = sck->connect("irc.euirc.net", 6667, sf::seconds(5.0f));
if (status != sf::Socket::Done)
{
std::cout << "Error on connect!" << std::endl;
return 1;
}
std::cout << "Connect was successful!" << std::endl;
return 0;
}
int loginOnIRC(sf::TcpSocket* sck)
{
receive(sck); // We get a Ping timeout here
std::string data{ "NICK NimBot" };
if(sck->send(data.c_str(), data.length()) != sf::Socket::Done)
{
std::cout << "Error on sending " << data << std::endl;
return 1;
}
receive(sck);
data = "USER NimBot * * :Nimelrians Bot";
if (sck->send(data.c_str(), data.length()) != sf::Socket::Done)
{
std::cout << "Error on sending " << data << std::endl;
return 1;
}
receive(sck);
data = "JOIN #nimbottest";
if (sck->send(data.c_str(), data.length()) != sf::Socket::Done)
{
std::cout << "Error on sending " << data << std::endl;
return 1;
}
return 0;
}
int main()
{
sf::TcpSocket sck{};
establishConnection(&sck); // works
loginOnIRC(&sck);
while(true)
{
char data[100];
memset(data, 0, ARRAY_LEN(data));
std::size_t received;
sf::Socket::Status rcvStatus = sck.receive(data, ARRAY_LEN(data), received);
if (rcvStatus != sf::Socket::Done)
{
std::cout << "oops" << std::endl;
if (rcvStatus == sf::Socket::Disconnected)
{
break;
}
}
std::cout << "Received " << received << " bytes" << std::endl;
std::cout << data << std::endl;
}
return 0;
}