DaniWeb IT Discussion Community

DaniWeb IT Discussion Community (http://www.daniweb.com/forums/index.php)
-   C++ (http://www.daniweb.com/forums/forum8.html)
-   -   winsock help (http://www.daniweb.com/forums/thread138888.html)

Nemoticchigga Aug 6th, 2008 4:32 pm
winsock help
 
I am trying to run a simple program to read ethernet using UDP. Here is the code, but it always receives -1 for 'error', but I did it by the book. Do you guys see the problem? Thanks.

//enum specifying the current status of the comm port.
enum e_PortStatus
{
        PORT_BUSY,                                                                        //port is currently in use
        PORT_READY,                                                                        //port is setup and ready for communication
        PORT_ERROR                                                                        //an error has occured somewhere
};

e_PortStatus myPortStatus;

//methods
void InitializeDevice();                                        //method which sets up this class, called at startup
void SetupPort();                                                        //method which readies the port for communications
void SendCommandToDevice();                                        //method which passes in parameters defining a message to be sent to the device on the port

static struct sockaddr_in mySocketAddress;                        //used to keep track of the connector's address
static struct sockaddr_in theirSocketAddress;                //used to keep track of the connector's address
static int socket_fd;                                                                //Socket File Descriptor
void StartDevice();                                                                        //Initializes the WINSOCK API
void CloseDevice();                                                                        //Close the WINSOCK API


void InitializeDevice()
{
        SetupPort();       
}

void SetupPort()
{
        int yes = 1;

        StartDevice();
        if (myPortStatus != PORT_READY)
                CloseDevice();

        // create a UDP-based socket
        socket_fd = socket(PF_INET, SOCK_DGRAM, 0);
        if (socket_fd == -1)
        {
                myPortStatus = PORT_ERROR;
                cout << "CANNOT CREATE SOCKET" << endl;
                CloseDevice();               
        }
       
        if (setsockopt(socket_fd, SOL_SOCKET, SO_REUSEADDR, (char* )&yes, sizeof(int)) == -1)
        {
                cout << "setsockopt" << endl;
                CloseDevice();
        }

        // set up the local address
        mySocketAddress.sin_family = AF_INET;
        mySocketAddress.sin_port = htons(2010); //My_Port_Number
        mySocketAddress.sin_addr.s_addr = htonl(INADDR_ANY); //automatically fills in the IP address of the machine the process is running on

        // bind in socket to local address (sockaddr)
        if (bind(socket_fd, (sockaddr *) &mySocketAddress, sizeof (mySocketAddress)) == -1)
        {
                myPortStatus = PORT_ERROR;
                cout << "CANNOT BIND SOCKET" << endl;
                int error = WSAGetLastError();
                CloseDevice();       
        }
}

char* ReceiveCommandFromDevice()
{
        char* messageBuf = NULL;
        int size_received;
        int dwtheirSocketAddressSize;

        /*Start of broadcast
        //Only use if you want to broadcast to every address on the network
        //So change theirSocketAddress.sin_addr.s_addr to INADDR_BROADCAST and uncomment
        if (setsockopt(socket_fd, SOL_SOCKET, SO_BROADCAST, (char* )&broadcast, sizeof(broadcast)) == -1)
        {

                myPortStatus = PORT_ERROR;
                perror("setsockopt (SO_BROADCAST)");
                CloseDevice();
       
        }
        //end of broadcast

        */

        //make sure Port is set to Ready Mode
        if ( myPortStatus == PORT_READY)
        {
                myPortStatus = PORT_BUSY;

                size_received = recvfrom(socket_fd, messageBuf, sizeof(messageBuf), MSG_WAITALL, (SOCKADDR*) &theirSocketAddress, &dwtheirSocketAddressSize);
               
                //check for error
                if (size_received == -1)
                {
                        myPortStatus = PORT_ERROR;
                        //cout << "CANNOT RECEIVE FROM PORT" << endl;
                        CloseDevice();
                        messageBuf = 'FAILURE';
                }
                else
                        myPortStatus = PORT_READY;
        }

        return messageBuf;
}


void CloseDevice()
{
        closesocket(socket_fd);
        WSACleanup();
}

void StartDevice()
{
        WSADATA wsaData;
        int iResult;

        iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);

        if (iResult != 0)
        {
                myPortStatus = PORT_ERROR;
                cout << "WSAStartup failed" << endl;
                CloseDevice();
        }
        else
                myPortStatus = PORT_READY;
}


int _tmain(int argc, _TCHAR* argv[])
{
        InitializeDevice();

        char* message;

        while(1)
        {
                message = ReceiveCommandFromDevice();

                cout << "Received: " << message << endl << endl;

                Sleep(2000);
        }

        return 0;
}

Salem Aug 6th, 2008 5:27 pm
Re: winsock help
 
Probably because your use of messagebuf is broken in so many ways.

> size_received = recvfrom(socket_fd, messageBuf, sizeof(messageBuf),
messageBuf is NULL (1) and the sizeof is only the size of the pointer (2).
Since UDP is an "all-or-nothing" deal, if you can't fit the whole message into the space provided, then you don't get any of it. So any UDP packets larger than the typical 4-bytes for a pointer are just going to be dropped.

> messageBuf = 'FAILURE';
Please tell me your compiler told you this was bad?
Or do you just ignore all warnings and plough on until it crashes?

> int error = WSAGetLastError();
1. Add this to the call which fails.
2. Print it, so you know more.

Probably some other stuff, but that's enough for you to think about fixing.

And please don't just make messageBuf a char array and attempt to return it.


All times are GMT -4. The time now is 7:50 pm.

Forum system based on vBulletin Copyright ©2000 - 2009, Jelsoft Enterprises Ltd.
©2003 - 2009 DaniWeb® LLC