Thread: Troubles with Sockets

  1. #1
    Registered User
    Join Date
    Oct 2005
    Posts
    17

    Troubles with Sockets

    Hello together,
    this is my first thread here, but i think there will be some more

    Ok, here's my problem:
    I've written a simple client programm, which sends data to a server every 5 minutes or so.
    Because of this small amount of data, i always reopen a socket. But this socket doesn't close propertly, the connection stays in state TIME_WAIT.
    Every time i reopen a Socket, the programm also allocates about 8-12 kB of memory, and never frees it again.

    I will post my network code here, and i hope some of you guys are able to help me.

    Code:
    #include "stdafx.h"
    #include "NetworkHandler.h"
    
    #define NETWORK_ERROR -1
    #define NETWORK_OK     0
    #define SD_SEND 1
    #define SD_RECEIVE 1
    
    /* Prototypes */
    void ReportError(int errorCode, const char *whichFunc);
    
    char		buffer[256];				//Buffer for the message
    char		errorMsg[92];				//Buffer for the errorMessage
    WORD		sockVersion;
    WSADATA		wsaData;
    LPHOSTENT	hostEntry;
    SOCKADDR_IN serverInfo;
    SOCKET		theSocket;
    LINGER		theLinger;
    
    int nret;
    int connState;	
    
    /*
     * Main function, calls the other functions.
     */
    int connectToServer(void) {
    	connState = 0;
    	connState = initConnection();
    	connState = sendMessage();
    	closeConnection();
    
    	return connState;
    }
    
    /*
     *	Initialize the connection, by setting the server name and port
     *	Open the connection
     */
    int initConnection(){
    	sockVersion = MAKEWORD(1, 1);
    	WSAStartup(sockVersion, &wsaData);
    	
    	hostEntry = gethostbyname("127.0.0.1");
    
    	if (!hostEntry) {
    		nret = WSAGetLastError();
    		ReportError(nret, "gethostbyname()");
    		WSACleanup();
    		return NETWORK_ERROR;
    	}
    	
    	theSocket = socket(AF_INET,
    			   SOCK_STREAM,
    			   IPPROTO_TCP);	
    
    	theLinger.l_onoff = 1;
    	theLinger.l_linger = 0;
    	setsockopt(theSocket, SOL_SOCKET, SO_LINGER, (char *) &theLinger, sizeof(LINGER));
    
    	if (theSocket == INVALID_SOCKET) {
    		nret = WSAGetLastError();
    		ReportError(nret, "socket()");
    
    		WSACleanup();
    		return NETWORK_ERROR;
    	}
    
    
    	serverInfo.sin_family = AF_INET;
    	serverInfo.sin_addr = *((LPIN_ADDR)*hostEntry->h_addr_list);
    	serverInfo.sin_port = htons(13);
    
    	nret = connect(theSocket,
    		       (LPSOCKADDR)&serverInfo,
    		       sizeof(struct sockaddr));
    
    	if (nret == SOCKET_ERROR) {
    		nret = WSAGetLastError();
    		ReportError(nret, "connect()");
    		closesocket(theSocket);
    		WSACleanup();
    		return NETWORK_ERROR;
    	}
    	return 0;
    }
    
    
    /*
     *	Send data method
     */
    int sendMessage(){
    	ZeroMemory(buffer, 256);
    	wsprintf(buffer, "Some message");
    	nret = send(theSocket,
    		buffer,
    		strlen(buffer),
    	    0);
    	
    	if (nret == SOCKET_ERROR) {
    		closeConnection();
    		return NETWORK_ERROR;
    	}
    	return 0;
    }
    
    
    /*
     *	Close Socket
     */
    void closeConnection(){
    	int         b;
    	char        buf[256];
    
    	WSACancelBlockingCall();
    	shutdown(theSocket, SD_SEND);
    	while ((b = recv(theSocket, buf, 256, 0)) != 0)
    		if (b == SOCKET_ERROR)
    			break;
    	shutdown(theSocket, SD_RECEIVE);
    	closesocket(theSocket);
    	WSACleanup();
    }
    
    void ReportError(int errorCode, const char *whichFunc) {
       ZeroMemory(errorMsg, 92);
       sprintf(errorMsg, "Call to %s returned error %d!", (char *)whichFunc, errorCode);
       MessageBox(NULL, errorMsg, "NetworkError", MB_OK);
    }
    I have this problem since a few days so i hope somebody has a solution for this. Thank you.

  2. #2
    train spotter
    Join Date
    Aug 2001
    Location
    near a computer
    Posts
    3,868
    Been a while but I remember having a similar problem....


    have you tried setsockopt() with a SO_DONTLINGER?
    "Man alone suffers so excruciatingly in the world that he was compelled to invent laughter."
    Friedrich Nietzsche

    "I spent a lot of my money on booze, birds and fast cars......the rest I squandered."
    George Best

    "If you are going through hell....keep going."
    Winston Churchill

  3. #3
    Registered User
    Join Date
    Oct 2005
    Posts
    17
    Well, the connections closing now, i had to set the LINGER on the serverside too. But thanks for your answer.
    But i still have the problem of the memory leak. Every time a connection is closed, the memory is left allocated.
    Any suggestions about that?
    I dont really have a clue why this is happening.

  4. #4
    train spotter
    Join Date
    Aug 2001
    Location
    near a computer
    Posts
    3,868
    Looks OK to me ...... but been a while since I did sockets.

    You could.......

    Check the return from WSACleanup()

    and look at bind()
    "Man alone suffers so excruciatingly in the world that he was compelled to invent laughter."
    Friedrich Nietzsche

    "I spent a lot of my money on booze, birds and fast cars......the rest I squandered."
    George Best

    "If you are going through hell....keep going."
    Winston Churchill

  5. #5
    Unregistered User
    Join Date
    Sep 2005
    Location
    Antarctica
    Posts
    341
    how is this code called? You don't want to call WSAStartup and WSACleanup over and over, only call them once at the start and end of the program.

  6. #6
    Registered User
    Join Date
    Oct 2005
    Posts
    17
    This Code is called over a Timer every 5 minutes or so.
    Well i'll try to call WSAStartup() and WSACleanup() only once, but i dont think this will solve my problem. The problem seems to be the socket.

    Edit: I have changed my code as you said, and it seems to work now. Thank you very mutch, i browsed the net for a solution of this for many hours
    Last edited by cornholio; 10-25-2005 at 11:56 PM.

  7. #7
    Registered User
    Join Date
    Sep 2004
    Posts
    57
    Hello cornholio,

    I played with your code and I have questions about it, but rather than ask you, I thought it might be easier if I posted a simple client/server example, then you could see if maybe your code could be corrected. (You probably don't need this server, but I give it anyway.)

    Here goes...the Client simply repeatedly sets up/ breaks down a connection.

    The simple Client:
    Code:
    // I compile/link with gcc (let me know if you want the vc compile/link commands)
    //gcc myclient.c -lws2_32 -o myclient.exe
    #include <windows.h>
    #include <stdio.h>
    #include <winsock.h>
    
    #define DEST_IP_ADDR "127.0.0.1"
    #define PORT (u_short) 13
    
    int main()
    {
       #define MAXBUFLEN 256
       WSADATA Data;
       SOCKET destSocket;
       SOCKADDR_IN destSockAddr;
       unsigned long destAddr;
       int status;
       int numsnt;
       char sendText[MAXBUFLEN] = "Some message";
    
    
       while(1) {
    
          status = WSAStartup(MAKEWORD(1, 1), &Data);
          if (status != 0)
             { printf("WSAStartup unsuccessful\n"); }
          
          destSocket = socket(AF_INET, SOCK_STREAM, 0);
          if (destSocket == INVALID_SOCKET) {
             printf("socket unsuccessful\n");
             status = WSACleanup();
             if (status == SOCKET_ERROR)
                { printf("WSACleanup unsuccessful\n"); }
             return(1);
          }
          
          destAddr = inet_addr(DEST_IP_ADDR);
          memcpy(&destSockAddr.sin_addr, &destAddr, sizeof(destAddr));
          destSockAddr.sin_port = htons(PORT);
          destSockAddr.sin_family = AF_INET;
          
          printf("Trying to connect to IP Address: %s\n",DEST_IP_ADDR);
          
          status = connect(destSocket, (LPSOCKADDR) &destSockAddr, sizeof(destSockAddr));
          if (status == SOCKET_ERROR) {
             printf("connect unsuccessful\n");
             status = closesocket(destSocket);
             if (status == SOCKET_ERROR)
                { printf("closesocket unsuccessful\n"); }
             status = WSACleanup();
             if (status == SOCKET_ERROR)
                { printf("WSACleanup unsuccessful\n"); }
             return(1);
          }
          
          printf("Connected...\n");
       
          //printf("Type text to send: ");
          //gets(sendText);
          
          numsnt = send(destSocket, sendText, strlen(sendText) + 1, 0);
          if (numsnt != (int)strlen(sendText) + 1) {
             printf("Connection terminated.\n");
             status = closesocket(destSocket);
             if (status == SOCKET_ERROR)
                { printf("closesocket unsuccessful\n"); }
             status = WSACleanup();
             if (status == SOCKET_ERROR)
                { printf("WSACleanup unsuccessful\n"); }
             return(1);
          }
          
          status = closesocket(destSocket);
          if (status == SOCKET_ERROR)
             { printf("closesocket unsuccessful\n"); }
          status = WSACleanup();
          if (status == SOCKET_ERROR)
             { printf("WSACleanup unsuccessful\n"); }
    
          printf("Connection terminated.\n");
    
          //Sleep(10000);  // wait 10 seconds
       
       } /* while */
    }


    The simple Server:
    Code:
    //gcc myserver.c -lws2_32 -o myserver.exe
    #include <windows.h>
    #include <stdio.h>
    #include <winsock2.h>
    #include <process.h>
    
    #define NO_FLAGS_SET 0
    
    #define PORT (u_short) 13
    #define MAXBUFLEN 256
    
    VOID talkToClient(VOID *cs) {
       char buffer[MAXBUFLEN];
       int status;
       int numsnt;
       int numrcv;
       
       SOCKET clientSocket = (SOCKET)cs;
       
       while(1) {
          numrcv = recv(clientSocket, buffer, MAXBUFLEN, NO_FLAGS_SET);
          if ((numrcv == 0) || (numrcv == SOCKET_ERROR)) {
             printf("Connection terminated\n");
             break;
          }
          //printf("n= %i",numrcv);
          buffer[numrcv] = '\0';
          printf("Received: %s\n",buffer);
    
          //_strupr(buffer);
          
          numsnt = send(clientSocket, buffer, strlen(buffer) + 1, NO_FLAGS_SET);
          if (numsnt != (int)strlen(buffer) + 1) {
             printf("Connection terminated.");
             break;
          }
       
       } /* while */
       
       status = shutdown(clientSocket, 2);
       if (status == SOCKET_ERROR)
          { printf("shutdown unsuccessful"); }
       
       status = closesocket(clientSocket);
       if (status == SOCKET_ERROR)
          { printf("closesocket unsuccessful"); }
    }
    
    int main(VOID) {
       WSADATA Data;
       SOCKADDR_IN serverSockAddr;
       SOCKADDR_IN clientSockAddr;
       SOCKET serverSocket;
       SOCKET clientSocket;
       int addrLen=sizeof(SOCKADDR_IN);
       int status;
       DWORD threadID;
       
       /* initialize the Windows Socket DLL */
       status=WSAStartup(MAKEWORD(1, 1), &Data);
       if (status != 0) {
          printf("WSAStartup unsuccessful");
          return(1);
       }
       
       
       memset(&serverSockAddr, 0, sizeof(serverSockAddr));
       serverSockAddr.sin_port        = htons(PORT);
       serverSockAddr.sin_family      = AF_INET;
       serverSockAddr.sin_addr.s_addr = htonl(INADDR_ANY);
       
       serverSocket = socket(AF_INET, SOCK_STREAM, 0);
       if (serverSocket == INVALID_SOCKET) {
          printf("ERROR: socket unsuccessful");
          status = WSACleanup();
          if (status == SOCKET_ERROR)
             { printf("WSACleanup unsuccessful"); }
          return(1);
       }
       
       status = bind(serverSocket, (LPSOCKADDR) &serverSockAddr, sizeof(serverSockAddr));
       if (status == SOCKET_ERROR)
          { printf("bind unsuccessful"); }
       
       status = listen(serverSocket, 1);
       if (status == SOCKET_ERROR)
          { printf("listen unsuccessful"); }
       
       while(1) {
       
          clientSocket = accept(serverSocket, (LPSOCKADDR) &clientSockAddr, &addrLen);
          if (clientSocket == INVALID_SOCKET) {
             printf("Unable to accept connection");
             return(1);
          }
          
          threadID = _beginthread(talkToClient, 0, (VOID *)clientSocket);
          if (threadID == -1) {
             printf("Unable to create thread");
             status = closesocket(clientSocket);
             if (status == SOCKET_ERROR)
                { printf("closesocket unsuccessful"); }
          }
       
       }
    }

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Best way to poll sockets?
    By 39ster in forum Networking/Device Communication
    Replies: 3
    Last Post: 07-22-2008, 01:43 PM
  2. Cross platform sockets
    By zacs7 in forum Networking/Device Communication
    Replies: 5
    Last Post: 06-27-2007, 05:16 AM
  3. multiple UDP sockets with select()
    By nkhambal in forum Networking/Device Communication
    Replies: 2
    Last Post: 01-17-2006, 07:36 PM
  4. Raw Sockets and SP2...
    By Devil Panther in forum Networking/Device Communication
    Replies: 11
    Last Post: 08-12-2005, 04:52 AM
  5. Starting window sockets
    By _Cl0wn_ in forum Windows Programming
    Replies: 2
    Last Post: 01-20-2003, 11:49 AM