Why "bad address" at ioctl() call - c++

I recently develop a program to wrap CAN bus feature into a class so it will be more reusable in future. I try to separate codes from long-single-file into main, header and implementation files.
So I have 3 files, "canbus.cpp", "canbus.h" and "main.cpp". Here are my code snippet:
canbus.h
#ifndef CANBUS_H
#define CANBUS_H
#include ... (some includes go here)
class CANBUS{
int CANbusSocket = 0; // Canbus socket number which is gained at initiation process by linux socket() function call.
const char* CANbusInterfaceName;
int CANbusReadMode;
struct can_frame frame;
struct ifreq ifr;
struct sockaddr_can addr;
can_err_mask_t err_mask;
public:
// canbus mode mode: 0-listen only, 1-request pgn
// canbus interface name: "can0", "can1"
CANBUS(int mode=0, const char* name="can1");
int init();
};
#endif
canbus.cpp
#include "canbus.h"
#include <iostream>
// Constructor
CANBUS::CANBUS(int mode, const char* name){
CANbusReadMode = mode;
CANbusInterfaceName = name;
}
int CANBUS::init(){
CANbusSocket = socket(PF_CAN, SOCK_RAW, CAN_RAW);
if( CANbusSocket == -1){
std::cout<<CANbusSocket<<std::endl;
fprintf(stderr, "Error socket: %s\n", strerror( errno ));
}
strcpy(ifr.ifr_name, CANbusInterfaceName );
if(ioctl(CANbusSocket, SIOCGIFINDEX, ifr) != 0){
std::cout<<CANbusSocket<<std::endl;
fprintf(stderr, "Error ioctl: %s\n", strerror( errno ));
}
addr.can_family = AF_CAN;
addr.can_ifindex = ifr.ifr_ifindex;
if(bind(CANbusSocket, (struct sockaddr *)&addr, sizeof(addr)) !=0){
std::cout<<CANbusSocket<<std::endl;
fprintf(stderr, "Error bind: %s\n", strerror( errno ));
}
if(setsockopt(CANbusSocket, SOL_CAN_RAW, CAN_RAW_ERR_FILTER, &err_mask, sizeof(err_mask))){ // enable error message frame
std::cout<<CANbusSocket<<std::endl;
fprintf(stderr, "Error setsockopt: %s\n", strerror( errno ));
}
return 0;
}
main.cpp
#include "canbus.h"
#include <iostream>
int main(){
errno = 0;
const char* interfaceName = "can1";
int readMode = 0;
CANBUS can1(readMode, interfaceName);
can1.init();
// ... some codes here
return 0;
}
when I build with g++ and then run it, it will give error at ioctl() like this:
Error ioctl: Bad address
To note:
This kind program works previously which was written in the previous long-single-file code
Sequence in CANbus::init() is exactly the same order as previous code
variable for socket is now private while it was public in old
code
variable for socket is now accessed/assigned directly in CANbus::init() function while it was passed as pointer in previous CANbus::init(int* CANbusSocket) function
I've also tried to change CANbusSocket inside CANbus::init() from variable to pointer, but it gave me
Segmentation Fault

Related

Unable to call function in main (Inheritance in UDP Client App using C++)

I have created a separate UDP Server Application and a Client Application, and they are communicating with each other. I have tried to implement inheritance as the next step for this application (Base class : udp, child class: udpClient). I have developed the code for the client which I have presented my code below with comments as explanation.
I am having a problem in the last line of the code where the object is used to call the derived class. I do not know what parameters to give here. I have highlighted the problem area with comments. Any help is appreciated
EDIT : Also, 50003 is the port number right? If it was around 70000, the check should give an error right? But its not. What would be the problem?
UDP Client program
#include <iostream>
#include <WS2tcpip.h>
#pragma comment (lib, "ws2_32.lib")
using namespace std;
class udp {
protected:
WSADATA data;
WORD version = MAKEWORD(2, 2);
int wsOk = WSAStartup(version, &data);
public:
void checkudp()
{
if (wsOk != 0)
{
cout << "Can't start Winsock! " << wsOk;
return;
}
}
};
class udp_client : public udp {
private:
sockaddr_in server;
char clientIp[256];
int argc;
char* argv[];
public:
void udpworking(*int argc, char* argv[]*) { //PROBLEM HERE with call to main function
server.sin_family = AF_INET; // AF_INET = IPv4 addresses
server.sin_port = htons(50003); // Little to big endian conversion
inet_pton(AF_INET, "127.0.0.1", &server.sin_addr); // Convert from string to byte array
// Socket creation, note that the socket type is datagram
SOCKET out = socket(AF_INET, SOCK_DGRAM, 0);
// Write out to that socket
string s(argv[1]);
int sendOk = sendto(out, s.c_str(), s.size() + 1, 0, (sockaddr*)&server, sizeof(server));
if (sendOk == SOCKET_ERROR)
{
cout << "That didn't work! " << WSAGetLastError() << endl;
}
closesocket(out);
WSACleanup();
}
};
void main()
{
udp_client obj;
obj.udpworking(); //Parameter problem with function call
}
udp_client::udpworking requires two arguments, that you need to pass in parameters (in the parenthesis).
Also as mentioned in the comments void main() is not a valid signature for this function. Only int main() (which ignores all parameters) and int main(int argc, char **argv) (which takes in the command line parameters) are valid signatures.
Try something like this:
int main(int argc, char **argv) {
udp_client obj;
obj.udpworking(argc, argv);
return 0;
}
PS: I take it you added the stars surrounding the parameters in the functions when you posted it on SO? (the udpworking(*int argc, char* argv[]*))

socket recv read no message

The following code is an application supposed to be communicating between two applications. In one exe (A) user type a message and the message is printed in the other exe(B).
The flow of the program:
Both exe calls connectTo so they are ready to send and receive messages between.
User type a message to be send in A console window, which calls sendMsg in A exe. When message is received in B, the message is printed in B console window.
The problem is that the message received is sometimes empty. When I enter 1234 ten times in A, ten messages are printed in B with only 5-6 of them are 1234 and the rest are empty. The situation is the same from B to A.
++++++++++++++++++++++++++
whole program
++++++++++++++++++++++++++
Header.h
#pragma once
#include <WinSock2.h>
#include <Windows.h>
#include <mutex>
#include <thread>
class CommuWin
{
private:
std::mutex m_accessMutexSend;
std::mutex m_accessMutexReceive;
std::thread m_sendThread;
std::thread m_receiveThread;
bool m_IsSendReady = false;
bool m_IsRecvReady = false;
SOCKET m_outSocket;
SOCKADDR_IN m_outAddr;
SOCKET m_inSocket;
SOCKADDR_IN m_inAddr;
public:
CommuWin(int InPort, int OutPort);
~CommuWin();
int connectTo();
int sendMsg(const char* message);
int StartReceiveMsg();
bool GetRecvStatus();
bool GetSendStatus();
private:
void SetRecvStatus(bool ready);
void SetSendStatus(bool ready);
int SetupRecvEnd();
int SetupSendEnd();
int sendMsgTo(const char* message);
int ReceiveMsgFrom();
};
Source.cpp
#pragma comment(lib, "Ws2_32.lib")
#include "Header.h"
#define OKAY (1)
#define ERROR (-1)
#define MAX_MSG_SIZE (200)
class NetworkServices
{
public:
static int sendMessage(SOCKET curSocket, const char* message, int messageSize);
static int receiveMessage(SOCKET curSocket, char * buffer, int bufSize);
};
int NetworkServices::sendMessage(SOCKET curSocket, const char* message, int messageSize)
{
return send(curSocket, message, messageSize, 0);
}
int NetworkServices::receiveMessage(SOCKET curSocket, char * buffer, int bufSize)
{
return recv(curSocket, buffer, bufSize, 0);
}
CommuWin::CommuWin(int InPort, int OutPort)
{
WSAData wsaData;
WORD DLLVersion;
DLLVersion = MAKEWORD(2, 1);
int r = WSAStartup(DLLVersion, &wsaData);
///////////////////////////////////////////////////////////////////////
m_outSocket = socket(AF_INET, SOCK_STREAM, NULL);
m_outAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
m_outAddr.sin_family = AF_INET;
m_outAddr.sin_port = htons(OutPort);
m_inSocket = socket(AF_INET, SOCK_STREAM, NULL);
m_inAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
m_inAddr.sin_family = AF_INET;
m_inAddr.sin_port = htons(InPort);
}
CommuWin::~CommuWin()
{
}
int CommuWin::connectTo()
{
printf("connect to");
printf("\n");
m_sendThread = std::thread(
&CommuWin::SetupSendEnd,
this);
m_receiveThread = std::thread(
&CommuWin::SetupRecvEnd,
this);
return OKAY;
}
int CommuWin::SetupSendEnd()
{
SOCKET sListen;
sListen = socket(AF_INET, SOCK_STREAM, NULL);
bind(sListen, (SOCKADDR*)&m_outAddr, sizeof(m_outAddr));
listen(sListen, SOMAXCONN);
m_outSocket = accept(sListen, NULL, NULL);
if (m_outSocket != INVALID_SOCKET)
{
SetSendStatus(true);
printf("accepted\n");
}
return OKAY;
}
int CommuWin::SetupRecvEnd()
{
int connectSucceed = 0;
do
{
Sleep(1000);
connectSucceed = connect(m_inSocket, (SOCKADDR*)&m_inAddr, sizeof(m_inAddr));
} while (connectSucceed == SOCKET_ERROR);
SetRecvStatus(true);
printf("connected\n");
return OKAY;
}
int CommuWin::sendMsg(const char* message)
{
if (GetSendStatus())
{
m_sendThread.detach();
m_sendThread = std::thread(
&CommuWin::sendMsgTo,
this,
message);
}
return OKAY;
}
int CommuWin::sendMsgTo(const char* message)
{
NetworkServices::sendMessage(m_outSocket, message, (int)strlen(message));
return OKAY;
}
int CommuWin::StartReceiveMsg()
{
if (GetRecvStatus())
{
m_receiveThread.detach();
m_receiveThread = std::thread(
&CommuWin::ReceiveMsgFrom,
this);
}
return OKAY;
}
int CommuWin::ReceiveMsgFrom()
{
while (true)
{
char message[MAX_MSG_SIZE];
ZeroMemory(message, MAX_MSG_SIZE);
NetworkServices::receiveMessage(m_inSocket, message, sizeof(message));
printf(message);
printf("\n");
}
return OKAY;
}
void CommuWin::SetRecvStatus(bool ready)
{
std::lock_guard<std::mutex> lock(m_accessMutexReceive);
m_IsRecvReady = ready;
}
void CommuWin::SetSendStatus(bool ready)
{
std::lock_guard<std::mutex> lock(m_accessMutexSend);
m_IsSendReady = ready;
}
bool CommuWin::GetRecvStatus()
{
std::lock_guard<std::mutex> lock(m_accessMutexReceive);
return m_IsRecvReady;
}
bool CommuWin::GetSendStatus()
{
std::lock_guard<std::mutex> lock(m_accessMutexSend);
return m_IsSendReady;
}
main.cpp
#include "stdafx.h"
#include "Header.h"
#include <iostream>
#include <string>
int main(int argc, char *argv[])
{
std::cout << argc <<std::endl;
int Inport = std::stoi(argv[1]);
int Outport = std::stoi(argv[2]);
//std::cout << "inport = " << argv[1] << " outport = " << argv[2] << std::endl;
std::cout << "inport = " << Inport << " outport = " << Outport << std::endl;
CommuWin com(Inport, Outport);
com.connectTo();
while (true)
{
if (com.GetSendStatus() && com.GetRecvStatus())
{
com.StartReceiveMsg();
break;
}
}
while (true)
{
std::cout << "Enter Send Message" << std::endl;
std::string msg;
std::cin >> msg;
com.sendMsg(msg.c_str());
}
return 0;
}
There are multiple issues with your code. First of all, you need to check results of all the functions, including, but not limited to, to sListen, bind, listen, recv.
NetworkServices::receiveMessage(m_inSocket, message, sizeof(message));
// Without checking recv result there is no way to guess how much
// bytes are actually stored in `message`, if any. Also boldly assuming
// that `message` is null terminated and represents a proper format string
// is dangerous.
printf(message);
You also need to carefully initialize all the stuff, especially sockaddr structures, which may get potentially partially initialized in this case. You are using multiple threads but perform insufficient synchronization. Method sendMsgTo(const char* message) executed by (potentially detached) background thread receives a pointer to a string buffer that may get invalidated at any time.
If you want to send and receive messages, you have to write some code to do that. Nowhere is there any code to send or receive messages. If you think there is, point specifically to the code that figures out whether or not the data you received is one or more messages. You cannot do it.
TCP is not a message protocol. If you need a message protocol on top of TCP, you have to implement one. Have a look at protocols that do this such as HTTP, IRC, or FTP so see how it's done.
If you log the number of bytes received, you will see that all the data you sent was received. It's your job to split that data into messages if you need to -- it won't happen by itself.

TeamSpeak 3 SDK Connection problems

I´m trying to use the TeamSpeak SDK for a personal project, but the code I wrote gives me weird errors.
I read the documentation many times to find an error but I can´t see why my program is not able to connect to the TeamSpeak Server.
Here is the output from the program:
Client library version: 3.0.3.2 [Build: 1433933257] SDK
Connection Status changed to: 1, errorNumber: 0
Connection Status changed to: 0, errorNumber: 1797
failed connection initialization
Here is the program code
#include <iostream>
#include <fstream>
#include <cstring>
#include <teamspeak/clientlib.h>
#include <teamspeak/public_errors.h>
uint64 connectionHandler;
void destroy();
void event_connectStatusChanged(uint64 serverConnectionIDHandler, int newStatus, unsigned int errorNumber);
void event_serverError(uint64 serverConnectionHandlerID, const char* errorMessage, unsigned int error, const char* returnCode, const char* extraMessage);
int main()
{
ClientUIFunctions uiFunctions;
memset(&uiFunctions, 0, sizeof(struct ClientUIFunctions));
uiFunctions.onConnectStatusChangeEvent = event_connectStatusChanged;
uiFunctions.onServerErrorEvent = event_serverError;
unsigned int error = ts3client_initClientLib(&uiFunctions, NULL, LogType_FILE, NULL, "./");
if (error != ERROR_ok)
printf("Error initializing clientlib: %i\n", error);
char* version;
error = ts3client_getClientLibVersion(&version);
if (error != ERROR_ok) {
printf("Error querying clientlib version: %d\n", error);
return 0;
}
printf("Client library version: %s\n", version); /* Print version */
ts3client_freeMemory(version); /* Release string */
if (ts3client_spawnNewServerConnectionHandler(0, &connectionHandler) != ERROR_ok)
{
destroy();
return 0;
}
char* identity;
ts3client_createIdentity(&identity);
error = ts3client_startConnection(connectionHandler, identity, "127.0.0.1", 9987, "test", NULL, "", "");
ts3client_freeMemory(identity);
if (error != ERROR_ok)
std::cout << "Connection failed!" << std::endl;
getchar();
ts3client_stopConnection(connectionHandler, "...");
destroy();
return 0;
}
void event_connectStatusChanged(uint64 serverConnectionIDHandler, int newStatus, unsigned int errorNumber)
{
printf("Connection Status changed to: %i, errorNumber: %i\n", newStatus, errorNumber);
if (errorNumber != ERROR_ok)
{
char* error;
ts3client_getErrorMessage(errorNumber, &error);
std::cout << error << std::endl;
ts3client_freeMemory(error);
}
}
void event_serverError(uint64 serverConnectionHandlerID, const char* errorMessage, unsigned int error, const char* returnCode, const char* extraMessage)
{
std::cout << "ERROR: " << errorMessage << std::endl << "Extra Message: " << extraMessage << std::endl;
}
void destroy()
{
ts3client_destroyServerConnectionHandler(connectionHandler);
ts3client_destroyClientLib();
}
It appears your client crashes immediately on connecting.
Here are some common causes to check:
Server doesn't exist at that address.
Server password is wrong.
Default channel doesn't exist.
Client has been banned.
Server is an illegal installation.
Security level of your identity is too low.
Also, this error can be triggered when a component such as client, server, etc need to be updated:
I updated to the latest version because the bot wouldn't launch and
figured I'd give the install on my other server another try. It's
working flawlessly now.
Ref: https://forum.sinusbot.com/threads/new-connection-status-0-error-1797.2508/

C++ constructor not being called [duplicate]

This question already has answers here:
Default constructor with empty brackets
(9 answers)
Closed 4 years ago.
I'm new to C++ and this is my first time with its classes and I was wondering, how do I call a constructor? I've read some documentation on classes in C++ and that's how I came up with what I have. The constructor calls private methods to setup the server.
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sstream>
#include <string>
#include "SimpleIni.h"
#include "MySQL.cpp"
#include <thread>
class LoginServer {
int resSocket;
MySQL mysql;
struct sockaddr_in strctAddr;
private:
void log(std::string strText, std::string strType = "INFO"){
time_t rawtime;
struct tm * timeinfo;
char buffer[50];
time(&rawtime);
timeinfo = localtime(&rawtime);
strftime(buffer, 50, "%c",timeinfo);
std::cout << "[" << buffer << "][" << strType << "] > " << strText << std::endl;
}
void error(std::string strError){
log(strError, "ERROR");
exit(1);
}
int setup(int intPort){
std::stringstream objStringStream;
objStringStream << intPort;
log("Initializing socket server");
resSocket = socket(AF_INET, SOCK_STREAM, 0);
if(resSocket < 0) error("Could not create socket.");
bzero((char *) &strctAddr, sizeof(strctAddr));
strctAddr.sin_family = AF_INET;
strctAddr.sin_addr.s_addr = INADDR_ANY;
strctAddr.sin_port = htons(intPort);
setsockopt(resSocket, SOL_SOCKET, SO_REUSEADDR, (struct sockaddr *) &strctAddr, sizeof(strctAddr));
if(bind(resSocket, (struct sockaddr *) &strctAddr, sizeof(strctAddr)) < 0)
error("Could not bind");
listen(resSocket, 5);
log("Listening for clients on " + objStringStream.str(), "FINE");
return 1;
}
int sendPacket(int resSock, std::string strData){
int intWrite;
char chBuffer[8192];
strcpy(chBuffer, strData.c_str());
log("Sending packet: " + strData, "SEND");
intWrite = write(resSock, chBuffer, strlen(chBuffer) + 1);
return intWrite;
}
std::string RandomString(int len){
srand(time(0));
std::string str = "`~!##$%^&*()-=_+[]\{]|;:'\",<.>/?0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
int pos;
int size = str.size();
while(size != len) {
pos = ((rand() % (str.size() - 1)));
str.erase (pos, 1);
}
return str;
}
void handleData(int resSock, char* strData){
char * chData;
chData = strtok(strData, "\0");
while(chData != NULL){
std::string strPacket = chData;
log("Received data: " + std::string(strPacket), "RECV");
if(strPacket.compare("<policy-file-request/>") == 0){
log("Policy request received");
sendPacket(resSock, "<cross-domain-policy><allow-access-from domain='*' to-ports='6112'/></cross-domain-policy>");
} else if(strPacket.compare("<msg t='sys'><body action='verChk' r='0'><ver v='153' /></body></msg>") == 0){
log("Version check received");
sendPacket(resSock, "<msg t='sys'><body action='apiOK' r='0'></body></msg>");
}
chData = strtok(NULL, "\0");
}
}
void handleClient(int resSock){
char chBuffer[6486];
int intRead;
for(;;){
bzero(chBuffer, 6486);
intRead = read(resSock, chBuffer, 6486);
if(chBuffer == NULL) continue;
if(intRead <= 0){
log("Client disconnected");
close(resSock);
break;
} else {
handleData(resSock, chBuffer);
}
}
}
void listenToClients(){
for(;;){
std::stringstream objStringStream;
struct sockaddr_in clntAddr;
socklen_t intClients = sizeof(clntAddr);
int resClient = accept(resSocket, (struct sockaddr *) &clntAddr, &intClients);
if(resClient < 0) log("Failed to accept client", "ERROR");
setsockopt(resClient, SOL_SOCKET, SO_REUSEADDR, (struct sockaddr *) &clntAddr, sizeof(clntAddr));
char floatIP[INET_ADDRSTRLEN];
inet_ntop(AF_INET, &clntAddr.sin_addr, floatIP, sizeof floatIP);
objStringStream << floatIP;
log("New client connected (IP: " + objStringStream.str() + ")");
std::thread objThread(&LoginServer::handleClient, this, resClient);
objThread.detach();
}
}
public:
LoginServer();
};
LoginServer::LoginServer(){
CSimpleIniA objIniParser;
objIniParser.LoadFile("Settings.conf");
#define Host objIniParser.GetValue("Database", "Host", NULL)
#define User objIniParser.GetValue("Database", "User", NULL)
#define Pass objIniParser.GetValue("Database", "Pass", NULL)
#define Name objIniParser.GetValue("Database", "Name", NULL)
if(!mysql.connect(Host, User, Pass, Name)) error("Could not establish database connection.");
setup(6112);
listenToClients();
}
int main(){
LoginServer objLoginServer();
return 0;
}
Due to the rules of parsing in C++:
LoginServer objLoginServer();
doesn't declare an object of type LoginServer. In fact is declares a function that takes no parameters and returns a LoginServer object by value.
Instead you want to say:
LoginServer objLoginServer;
Try removing the parentheses:
LoginServer objLoginServer;
If you are curious of what's going on, search for the "most vexing parse".
The constructor should be called everytime you instantiate an object, such as the line LoginServer objLoginServer; (hint: try w/o the parenthesis) or LoginServer *objLoginServer = new LoginServer();, of course remember to call delete objLoginServer; when done with it.
There are multiple ways of calling the constructor, but I guess your specific problem is that your put brackets when calling default constructor, you need to omit them: LoginServer objLoginServer;
Such problem happens because compiler isn't able to distingush between declaring function prototype and calling default constructor. Look at A B(), out of context it may be creating object with name B of type A using default constructor, or function B returning an instance of type A.
http://www.cplusplus.com/doc/tutorial/classes/
Reading this is good start. Best of luck.
Important: Notice how if we declare a new object and we want to use its default constructor (the one without parameters), we do not include parentheses ():
CRectangle rectb; // right
CRectangle rectb(); // wrong!

Using select without listen()ing, possible?

I am building a client that:
Should be able to recieve information from both the server and the standart input
Should be able to recieve information from the server without asking, for example when another client sends a message.
To do so I tried using select to monitor both possible inputs.
What happens is that when a keyboard input is monitored I send a message to the client and I expect one back, so there's no problem. But when the server sends an unexpected message nothing happens, and I don't know why. Is using select() the proper way to do so? Is it even possible to use select() without listen()ing?
Here's my code (compileable):
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <netdb.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <cstring>
#include <arpa/inet.h>
#include <iostream>
#include <fstream>
#define MAX_CLIENT_NAME 30
#define MAX_TWIT_SIZE 140
#define NUM_OF_ARG 4
#define ERROR -1
#define GREAT_SUCCESS 0
#define OK "OK"
#define EXIT "EXIT"
using std::string;
using std::cerr;
using std::endl;
using std::cout;
string clientName;
int srverfd, numbytes, status, maxSock ;
fd_set inputFdSet; /* Socket file descriptors we want to wake
up for, using select() */
int establishConnection(char * serverAddress,char * port){
if ((srverfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
perror("socket");
return ERROR;
}
struct sockaddr_in server;
server.sin_family = AF_INET;
inet_aton(serverAddress, &server.sin_addr);
server.sin_port = htons(atoi(port));
memset(&(server.sin_zero), '\0', 8);
if (connect(srverfd,(const struct sockaddr *)&server,sizeof(struct sockaddr)) == -1) {
perror("connect");
close(srverfd);
return ERROR;
}
maxSock = srverfd;
return GREAT_SUCCESS;
}
const char * getUserTweet(){
string temp;
getline(std::cin,temp);
return temp.c_str();
}
void sendMessage(string message){
if ((numbytes = send(srverfd, message.c_str(), message.length(), 0)) == -1) {
perror("sendMessage");
close(srverfd);
}
cout<<"Message sent: "<< message << endl;
return;
}
const char * getMessage(){
char buf[MAX_TWIT_SIZE];
memset(buf,'\0',MAX_TWIT_SIZE);
if ((numbytes = recv(srverfd, buf, 140, 0)) == -1) {
perror("getMessage");
close(srverfd);
}
string temp = buf;
return temp.c_str();
}
void build_select_list() {
FD_ZERO(&inputFdSet);
FD_SET(srverfd,&inputFdSet);
FD_SET(STDIN_FILENO,&inputFdSet);
if (STDIN_FILENO > maxSock)
maxSock = STDIN_FILENO;
return;
}
void readSocket(fd_set tempfd) {
const char * tweet, * inMessage;
if (FD_ISSET(srverfd,&tempfd)) {
inMessage = getMessage();
cout << inMessage << endl;
}
if (FD_ISSET(STDIN_FILENO,&tempfd)) {
tweet = getUserTweet();
sendMessage(tweet);
inMessage = getMessage();
if (strcmp(inMessage,OK) != 0) {
cout << inMessage << endl;
}
if (strcmp(inMessage,EXIT) == 0) {
return;
}
}
return;
}
int main (int argc, char *argv[] ){
int value;
bool clientON = false;
if(establishConnection(argv[2],argv[3])){
cerr << "usage: failed to make connection" << endl << "exiting..." << endl;
exit(EXIT_FAILURE);
}
cout << "Connected successfully" << endl;
sendMessage("CONNECT "+clientName); //Connect
if(strcmp(getMessage(),OK) == 0){
clientON = true;
}
while(clientON){
build_select_list();
value = select(maxSock, &inputFdSet, NULL, NULL, NULL);
if (value < 0) {
perror("select");
exit(EXIT_FAILURE);
}
if (value == 0) {
continue;
}
else {
readSocket(inputFdSet);
}
}
sendMessage("DISCONNECT");
if(strcmp(getMessage(),OK) == 0){
// do nothing
}
close(srverfd);
return 0;
}
Your select call is invalid. The first parameter must be the highest file descriptor in any of the sets, plus one.
As you have it, an event on srverfd will not "wake up" the select call (unless STDIN_FILENO was somehow less than srverfd, in which case stdin events wouldn't unlock select - but that won't happen in practice).
There are quite a few other problems with your code. (It doesn't really look like C++.)
getUserTweet is unreliable (undefined behavior - temp is destroyed as soon as the function returns, so the char* you return has disappeared by the time its caller will try to use it). Same for getMessage. To remedy that, use std::string everywhere, and only extract the char* when you call into C library functions).
readSocket needlessly copies the FD set (can be expensive).
You should really get rid of all those globals - build one or two classes to encapsulate that state and the networking functions, or something like that.