I'm currently working to get some software that is currently running on windows ported over to ubuntu. One aspect of this software handles udp packets with the location of some of our assets using SFML. For some reason after moving OS's the packets are coming in as U� (always with the � symbol.) is this a posix problem? Here is the code I was using:
int32_t
SocketUdpClient::recv(std::string *data)
{
sf::Socket::Status recvStatus = sf::Socket::Error;
if( m_bOpen && data != NULL )
{
char buf[4096];
std::size_t bytesRead;
sf::IpAddress senderIp;
uint16_t senderPort;
recvStatus = m_socket.receive( buf, 4096, bytesRead, senderIp, senderPort );
if (recvStatus == sf::Socket::Done)
{
std::cout << "Received " << bytesRead << " bytes from " << senderIp << " on port " << senderPort << std::endl;
std::cout << buf <<std::endl;
m_senderIp = senderIp.toString();
if (m_listenAll)
{
m_peerIp = senderIp.toString();
printf("SocketUdpClient::recvfrom m_senderIp = %s, m_peerIp = %s\n", m_senderIp.c_str(), m_peerIp.c_str());
}
if (m_senderIp.compare(m_peerIp) == 0)
{
*data = std::string(buf, bytesRead);
return bytesRead;
//return senderIp.toString();
}
}
else if (recvStatus == sf::Socket::NotReady)
{
return 0;
}
}
return -1;
}
Change this:
recvStatus = m_socket.receive( buf, 4096, bytesRead, senderIp, senderPort );
if (recvStatus == sf::Socket::Done)
{
std::cout << "Received " << bytesRead << " bytes from " << senderIp << " on port " << senderPort << std::endl;
std::cout << buf <<std::endl;
To this:
bytesRead = 0; // always a good idea
recvStatus = m_socket.receive( buf, 4095 /* 1 less than buffer size*/, bytesRead, senderIp, senderPort );
if (recvStatus == sf::Socket::Done)
{
std::cout << "Received " << bytesRead << " bytes from " << senderIp << " on port " << senderPort << std::endl;
buf[bytesRead] = '\0'; // null terminate
std::cout << buf <<std::endl;
Related
void SendStr(int connfd, std::string str)
{
uint16_t *len = new uint16_t(str.size());
const char * lenByte = (char *)len;
char *sendByte = new char[*len + 2]{0};
memcpy(sendByte,lenByte,sizeof(*len));
memcpy(sendByte + 2, str.c_str(), *len);
std::cout << "str size " << *len << std::endl;
//std::cout << "len size " << sizeof(len) << std::endl;
size_t nleft = *len + 2;
std::cout << "need to send " << nleft << std::endl;
int nsend = 0;
while (nleft > 0)
{
//std::cout << "sending " << nleft << "bytes" << std::endl;
if (nsend = (write(connfd, sendByte + nsend, nleft)) < 0)
{
if (errno == EINTR)
continue;
ERROR_EXIT("send");
}
else if (nsend == 0)
//continue;
break;
nleft -= nsend;
std::cout << "sended " << nsend << " left " << nleft << std::endl;
}
std::cout << "send complete" << std::endl;
delete[] sendByte;
delete len;
}
The full code is here
I see write and send function return the sum of bytes, while here returns 0, and client seems run normally, it confuses me.
What you see is wrong.
In this statement
if (nsend = (write(connfd, sendByte + nsend, nleft)) < 0)
The comparision result of (write(connfd, sendByte + nsend, nleft)) < 0 is assingned to nsend. This will become 1 if the condition is true and 0 if the condition is false. It seems you are misunderstanding this comparision result as the sum of bytes.
If you want to assign what is returned from write to nsend and then compare, it should be like this:
if ((nsend = write(connfd, sendByte + nsend, nleft)) < 0)
Addendum: The only way for write to return 0 on a socket is if nleft is 0.
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 am trying to get information about all attached devices.
This is my code:
libusb_device_descriptor desc;
libusb_config_descriptor *conDesc;
char szBuffer[256] = { 0 };
unsigned char strDesc[256];
libusb_device_handle *devHandle = NULL;
int retVal = 0;
__int64 i64Temp;
DWORD dwProdId;
DWORD dwProdId1;
i64Temp = 13888;
dwProdId = (DWORD)i64Temp;
retVal = libusb_open(dev, &devHandle);
int r = libusb_get_device_descriptor(dev, &desc);
if (r < 0)
{
cout << "failed to get device descriptor" << endl;
return;
}
r = libusb_get_config_descriptor(dev, 0, &conDesc);
printf("Interface Class = %d\n", conDesc->interface->altsetting->bInterfaceClass);
cout << "Number of possible configurations: " << (int)desc.bNumConfigurations << "" << endl;
cout << "Device Class: " << desc.bDeviceClass << endl;
cout << "Device Class: " << desc.bDeviceSubClass << endl;
printf("Class = %d\n", desc.bDeviceClass);
cout << "VendorID: " << desc.idVendor << endl;
cout << "ProductID: " << desc.idProduct << endl;
if (retVal == LIBUSB_SUCCESS)
{
retVal = libusb_get_string_descriptor_ascii(devHandle, desc.iManufacturer, strDesc, 256);
printf("Manufacturer: %s\n", strDesc);
retVal = libusb_get_string_descriptor_ascii(devHandle, desc.iSerialNumber, strDesc, 256);
printf("SerialNumber: %s\n", strDesc);
retVal = libusb_get_string_descriptor_ascii(devHandle, desc.iProduct, strDesc, 256);
printf("Product: %s\n", strDesc);
printf("\n\n");
}
else if (retVal != LIBUSB_SUCCESS)
{
printf("retVal failed");
printf("\n\n");
}
My code knows that there are 8 devices connected but it's getting manufacturer or serial number only on two of them. I would like to get this information for all of the attached devices.
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;
}