Skip to main content
GameDev.net gamedev.net
🔒 Locked

Socket won't close [SOLVED]

Started by yukit0 Mar 21, 2005 at 3:52 PM 12 replies 2.4k views
Original Post
yukit0
yukit0
My program doesn't seem to close its socket, even though my destructor calls closesocket(sock); When i run the program again, the program says the adress is already in use. Any suggestions? [Edited by - yukit0 on March 21, 2005 4:44:40 PM]
Drew_Benton
Drew_Benton
You should probabally mention your code is here [wink] I am not a networking person, so I don't have anything specific to suggest.
yukit0
yukit0
Quote:
Original post by Drew_Benton
You should probabally mention your code is here [wink] I am not a networking person, so I don't have anything specific to suggest.


That is my code :P
yukit0
yukit0
erm when the program ends (normaly, at the end of main), doesn't the scope of my object end and doesnt the destructor get called?
Telastyn
Telastyn
Quote:
Original post by yukit0
erm when the program ends (normaly, at the end of main), doesn't the scope of my object end and doesnt the destructor get called?


*scratches head*

Sorry, I don't often use normal variables and take advantage of scoping...

so you're doing something like this:

socketclass{    socketclass(){        socket(sock...);        bind(sock...);        listen(sock...);    }    ~socketclass(){        closesocket(sock);    }}int main(int argc, char *argz[]){socketclass   socket_instance;// stuff}


Then socket_instance should be created at the beginning of main and destroyed at the end, as long as you're calling return from main. If you're calling exit() or something else, I am unsure as to the scoping involved there...

Like Drew said, perhaps post the entirety of your code if that doesn't help so much.
yukit0
yukit0
i posted it in another post but here it is again:

sockity.h:
/*    Sockity - A primitive Berkeley socket and Winsock wrapper.    Copyright (C) 2005 Wim Vander Schelden        This program is free software; you can redistribute it and/or    modify it under the terms of the GNU General Public License    as published by the Free Software Foundation; either version 2    of the License, or (at your option) any later version.        This program is distributed in the hope that it will be useful,    but WITHOUT ANY WARRANTY; without even the implied warranty of    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    GNU General Public License for more details.        You should have received a copy of the GNU General Public License    along with this program; if not, write to the Free Software    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA. */#ifdef _WIN32#include "winsock.h"#endif#ifdef _UNIX#include "sys/socket.h"#include "netinet/in.h"#include "netdb.h"#endif#include "stdio.h"#include "stdlib.h"using namespace std;/* Status constants */const int CLOSED = 0, CONNECTED = 1, LISTENING =2; class sockity {      public:            /* Almighty error handling, ripped from Rip7's code */            class ErrorHandling	        {                public:        		enum TypeOfError                    { WinsockInit, Create, Bind, UnknownHost, Connect,                      Linger };                ErrorHandling (TypeOfError S):Error (S)		        {		        }		        TypeOfError GiveError ()                {                return Error;		        }	            private:                TypeOfError Error;            };             /* Constructor */             sockity(unsigned short int port);             /* Destructor */             ~sockity();             /* Public Functions */             void conn(const char *hostname, unsigned short int port);             int getstatus() { return status; }      private:             /* Socket name */             sockaddr_in name;             /* Host socket name */             sockaddr_in hostname;             /* The almighty socket */             int sock;             /* Socket status */             int status;             /* Error code from socket */             //extern int h_errno;};


sockity.cpp:
/*    Sockity - A primitive Berkeley socket and Winsock wrapper.    Copyright (C) 2005 Wim Vander Schelden        This program is free software; you can redistribute it and/or    modify it under the terms of the GNU General Public License    as published by the Free Software Foundation; either version 2    of the License, or (at your option) any later version.        This program is distributed in the hope that it will be useful,    but WITHOUT ANY WARRANTY; without even the implied warranty of    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    GNU General Public License for more details.        You should have received a copy of the GNU General Public License    along with this program; if not, write to the Free Software    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA. */#ifdef _WIN32#include "winsock.h"#endif#ifdef _UNIX#include "sys/socket.h"#include "netinet/in.h"#include "netdb.h"#endif#include "stdio.h"#include "stdlib.h"#include "sockity.h"#include <iostream>using namespace std;sockity::sockity(unsigned short int port) {    #ifdef _WIN32    /* WIN32 socket initialization code */    WSADATA wsadata;    int rc = WSAStartup(2, &wsadata);    if(rc) {        throw ErrorHandling (ErrorHandling::WinsockInit);    }    #endif    /* Create the socket */    sock = socket(PF_INET, SOCK_STREAM, 0);    if (sock < 0)    {        throw ErrorHandling (ErrorHandling::Create);    }    /* Give the socket a name */    name.sin_family = AF_INET;    name.sin_port = htons(port);    name.sin_addr.s_addr = htonl(INADDR_ANY);    if (bind(sock, (sockaddr*) &name, sizeof(name)) < 0)    {        throw ErrorHandling (ErrorHandling::Bind);    }    linger *lngr;    lngr->l_onoff = 0;    lngr->l_linger = 0;    if (0 > setsockopt(sock, SOL_SOCKET, SO_LINGER, (char *)lngr, sizeof(*lngr)))    {        throw ErrorHandling (ErrorHandling::Linger);    }    status = CLOSED;}sockity::~sockity() {    #ifdef _WIN32        closesocket(sock);    #endif    #ifdef _UNIX        close(sock);    #endif}void sockity::conn(const char *host, unsigned short int port) {    hostent *hostinfo;    hostname.sin_family = AF_INET;    hostname.sin_port = htons(port);    unsigned long int ip;    ip = inet_addr(host);    hostname.sin_addr.s_addr = ip;    if (0 > connect(sock, (sockaddr *) &hostname, sizeof(hostname)))    {        if ( h_errno == 10049 ) {   // Host not found, try resolving it as a hostname            hostinfo = gethostbyname(host);            if (hostinfo == NULL)            {                throw ErrorHandling (ErrorHandling::UnknownHost);            }            hostname.sin_addr.S_un.S_un_b.s_b1 = (unsigned char)hostinfo->h_addr_list[0][0];            hostname.sin_addr.S_un.S_un_b.s_b2 = (unsigned char)hostinfo->h_addr_list[0][1];            hostname.sin_addr.S_un.S_un_b.s_b3 = (unsigned char)hostinfo->h_addr_list[0][2];            hostname.sin_addr.S_un.S_un_b.s_b4 = (unsigned char)hostinfo->h_addr_list[0][3];            if (0 > connect(sock, (sockaddr *) &hostname, sizeof(hostname)))            {                printf("Connection error: %d\n", h_errno);                throw ErrorHandling (ErrorHandling::Connect);            }        } else {            printf("Connection error: %d\n", h_errno);            throw ErrorHandling (ErrorHandling::Connect);        }    }    status = CONNECTED;}


test.cpp:
#include "sockity.h"#include <iostream>using namespace std;int main() {    try {        sockity scky(80);        scky.conn("www.google.be", 80);    } catch (sockity::ErrorHandling E) {        cout << "An error occured." << endl;        getc(stdin);        return 0;    }    cout << "Everything went ok." << endl;    getch(stdin);    return 0;}
yukit0
yukit0
oh and how do u create the white code snippets?
mike25025
mike25025
[ source ]code[ /source ]

dont put in the spaces
Telastyn
Telastyn
Try adding:

int    reuse=1;setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *)&reuse, sizeof(int));


before the bind() call.

This sort of setup is in all of the examples I've seen, and might help the addr in use error you're getting on a connect-only sort of setup like that. I think. Maybe....

[and of course, test if that function returns an error, and handle it appropriately.]
yukit0
yukit0
Doesn't change anything :(
achacha
achacha
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winsock/winsock/wsastartup_2.asp

WSAStartup must have a WSACleanup.



And from setsockopt documentation:


SO_LINGER Lingers on close if unsent data is present.


I suspect that is roughly where to start looking.
++Alex
yukit0
yukit0
Thanks so much you guys :) it works fine now :)
achacha
achacha
What fixed it?
++Alex

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.