delorie.com/archives/browse.cgi   search  
Mail Archives: cygwin/2008/09/25/04:23:22

X-Recipient: archive-cygwin AT delorie DOT com
X-Spam-Check-By: sourceware.org
From: sylvain DELHOMME <s DOT delhomme AT attitude-studio DOT com>
To: cygwin AT cygwin DOT com
Subject: socket not closed in a threaded server
Date: Thu, 25 Sep 2008 10:22:40 +0200
User-Agent: KMail/1.9.9
MIME-Version: 1.0
Message-Id: <200809251022.40547.s.delhomme@attitude-studio.com>
X-IsSubscribed: yes
Mailing-List: contact cygwin-help AT cygwin DOT com; run by ezmlm
List-Id: <cygwin.cygwin.com>
List-Subscribe: <mailto:cygwin-subscribe AT cygwin DOT com>
List-Archive: <http://sourceware.org/ml/cygwin/>
List-Post: <mailto:cygwin AT cygwin DOT com>
List-Help: <mailto:cygwin-help AT cygwin DOT com>, <http://sourceware.org/ml/#faqs>
Sender: cygwin-owner AT cygwin DOT com
Mail-Followup-To: cygwin AT cygwin DOT com
Delivered-To: mailing list cygwin AT cygwin DOT com

While playing with sockets and threads, I noticed that while my tcp socket is 
correctly closed, the associated udp socket (managed by Cygwin) is not. This 
was tested with(out) Firewall && Antivirus on 2 WinXP computers with cygwin 
1.5.25.

Is that a known problem with Cygwin (code is fine under Linux Debian) ?

testcase :

- ./main.exe (netstat shows 2 sockets (one tcp on port 1025 && one udp)
- telnet 127.0.0.1 1025 (netstat shows 4 sockets  : 2 tcp && 2 udp )
- netstat -ab shows 3 sockets (one tcp on port 1025 && two udp).

src :

--- begin ---

#include <stdlib.h>
#include <stdio.h>
#include <sys/socket.h>
#include <pthread.h>
#include <unistd.h>
#include <netinet/in.h>
#include <errno.h>
#include <string.h>

#define MAXTHREADS 4

pthread_mutex_t __mutex = PTHREAD_MUTEX_INITIALIZER;

struct thrdata {
	int thrnum;
	pthread_t t;
	int socket_fd;
	int socket_errno;
}th[MAXTHREADS];

int thread_code( void *p );

int main(int argc, char **argv)
{
	int fd;
	struct sockaddr_in sa;
	int i;

	sa.sin_family = AF_INET;
	sa.sin_addr.s_addr = htonl(INADDR_ANY);
	sa.sin_port = htons(1025);

	fd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);

	printf("socket id : %d\n", fd);

	if( bind( fd, (struct sockaddr *)&sa, sizeof(sa) ) == -1 )
		printf("bind error\n");

	if( listen( fd, 0 ) == -1 )
		printf("listen error\n");

	printf("creating threads\n");

	for(i=0; i<MAXTHREADS; i++)
	{
		th[i].thrnum = i;
		th[i].socket_fd = fd;
		printf("thread %d\n", i);
		pthread_create(&th[i].t, NULL, thread_code, (void *)&(th[i]));
		sleep(1);
	}

	for(i=0; i<MAXTHREADS; i++) 
	{
		pthread_join(th[i].t, NULL);
	}

	printf("exiting\n");

	return 1;
}

int thread_code( void *p )
{
	struct thrdata *pt = (struct thrdata *)p;
	int fd = pt->socket_fd;
	int fd_client;
	struct sockaddr_in sa_client;
	int sin_size;
	int i;
	char buf;

	// printf("thread, fd : %d\n", fd);

	for( ;; )
	{
		pthread_mutex_lock(&__mutex); /* begin critical area */	
		fd_client = accept( fd, (struct sockaddr *)&sa_client, &sin_size );
		
		if( fd_client < 0 )
			printf("accept error\n");

		pthread_mutex_unlock(&__mutex); /* end critical area */

		if( fd_client > 0 )
		{
			printf("accept fd : %d, fd_client : %d\n", fd, fd_client );
			for(i=0; i<20; i++)
			{
				send( fd_client, "hello\n", strlen("hello"), 0 );
				sleep(1);
			}
			
			printf("closing fd_client : %d\n", fd_client );
			close( fd_client );
		}
	}

	return 1;
}

--- end ---

--
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple
Problem reports:       http://cygwin.com/problems.html
Documentation:         http://cygwin.com/docs.html
FAQ:                   http://cygwin.com/faq/

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019