![]() |
| | #1 |
| Registered User Join Date: Oct 2005
Posts: 17
| Troubles with Sockets 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);
}
|
| cornholio is offline | |
| | #2 |
| train spotter Join Date: Aug 2001 Location: near a computer
Posts: 3,450
| 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 |
| novacain is offline | |
| | #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. |
| cornholio is offline | |
| | #4 |
| train spotter Join Date: Aug 2001 Location: near a computer
Posts: 3,450
| 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 |
| novacain is offline | |
| | #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. |
| rockytriton is offline | |
| | #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. |
| cornholio is offline | |
| | #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"); }
}
}
}
|
| cdave is offline | |
![]() |
| Thread Tools | |
| Display Modes | |
|
Similar Threads | ||||
| Thread | Thread Starter | Forum | Replies | Last Post |
| Best way to poll sockets? | 39ster | Networking/Device Communication | 3 | 07-22-2008 01:43 PM |
| Cross platform sockets | zacs7 | Networking/Device Communication | 5 | 06-27-2007 05:16 AM |
| multiple UDP sockets with select() | nkhambal | Networking/Device Communication | 2 | 01-17-2006 07:36 PM |
| Raw Sockets and SP2... | Devil Panther | Networking/Device Communication | 11 | 08-12-2005 04:52 AM |
| Starting window sockets | _Cl0wn_ | Windows Programming | 2 | 01-20-2003 11:49 AM |