J'ai un petit problème avec mes sockets que je ne m'explique pas. J'ai
deux applications qui font un connect() sur une troisième qui fait un
accept() pour "ouvrir" la socket. Mon problème c'est que les deux
accept() me disent qu'ils sont connectés alors que la troisième
application n'as fait qu'un seul accept(). Et en plus la socket est
configuré pour ne recevoir qu'une seule connexion ( listen( ..., 0) ).
Pour moi l'un des deux connect() devrair retourner une erreur puisque la
socket est déjà "ouverte". Précision supplémentaire, les deux
applications font leur connect() quasi simultanément et les sockets sont
non-bloquante. Je ne sais pas si c'est la cause du problème.
J'espère avoir été clair dans mon explication et que quelqu'un aurra une
idée. Ci joint le code de la fonction que fait le connect(), il y a
peut-être une erreur dedans !!!
Merci d'avance
Sylvain
static int connectWithTimeout( s, name, namelen, timeout )
int s; /* socket descriptor */
struct sockaddr *name; /* adress of the socket to connect */
int namelen; /* length of the socket, in bytes */
struct timeval *timeout; /* time-out value */
{
int on;
fd_set writefds;
int retval;
int peernamelen;
struct sockaddr peername;
/* when socket is set to non-blocking mode, connect () will return*/
/* with EINPROGRESS or EWOULDBLOCK if a connection cannot */
/* be setup immediatly */
if ( ( errno == EINPROGRESS ) || ( errno == EWOULDBLOCK ) )
{
/* we do synchronous polling on the write side of this socket */
/* using select() with the given <timeout> value until the */
/* connection gets established */
Sleep(10);
FD_ZERO( &writefds );
FD_SET( (unsigned int)s, &writefds );
// MODIF MH 051099
if ( select( 2000, NULL, &writefds, NULL, timeout ) > 0 )
{
/* select() is successful, see if our socket is actually */
/* selected for writing */
if (FD_ISSET (s, &writefds))
{
/* connection attempt has completed. We now see if it */
/* was a successful attempt by trying to get the */
/* remote perr's address. If getpeername () succeeds */
/* we have a connection, otherwise the connect() has */
/* failed */
Cette action est irreversible, confirmez la suppression du commentaire ?
Signaler le commentaire
Veuillez sélectionner un problème
Nudité
Violence
Harcèlement
Fraude
Vente illégale
Discours haineux
Terrorisme
Autre
Cyrille Szymanski
> J'ai deux applications qui font un connect() sur une troisième qui fait un accept() pour "ouvrir" la socket. Mon problème c'est que les deux accept() me disent qu'ils sont connectés alors que la troisième application n'as fait qu'un seul accept().
Je ne comprends pas vraiment. Comment accept() peut dire que les socket client sont connectées ?
Et en plus la socket est configuré pour ne recevoir qu'une seule connexion ( listen( ..., 0) ).
Ça c'est le "backlog" (la taille de la file d'attente pour les demandes de connexion *simultanées*)
Ce mélange unix/winsock est pas terrible. Avec winsock les types sont en majuscules, les paramètres socket ne sont pas des int mais des SOCKET (qui sont des entiers jusqu'à aujourd'hui).
SOCKET_ERROR est effectivement défini à (-1) mais c'est beaucoup mieux d'utiliser la macro.
static int connectWithTimeout( s, name, namelen, timeout ) int s; /* socket descriptor */
SOCKET s;
struct sockaddr *name; /* adress of the socket to connect */
SOCKADDR *name;
int namelen; /* length of the socket, in bytes */ struct timeval *timeout; /* time-out value */ { int on; fd_set writefds; int retval; int peernamelen; struct sockaddr peername;
SOCKARRD peername; /* note : n'est plus nécessaire */
/* put the socket s in non-blocking I/O mode to have the connect () */ /* return without pending */
on = 1;
ioctlsocket( s, FIONBIO, &on );
if ( connect( s, name, namelen ) < 0 )
== SOCKET_ERROR
{ errno = WSAGetLastError ();
/* when socket is set to non-blocking mode, connect () will return*/ /* with EINPROGRESS or EWOULDBLOCK if a connection cannot */ /* be setup immediatly */
Je ne suis pas certain que EINPROGRESS soit une erreur acceptable dans ce contexte.
Les erreurs sont WSAE... : WSAEINPROGRESS et WSAEWOULDBLOCK.
if ( ( errno == EINPROGRESS ) || ( errno == EWOULDBLOCK ) ) { /* we do synchronous polling on the write side of this socket */ /* using select() with the given <timeout> value until the */ /* connection gets established */
Sleep(10);
Ouh, pas beau du tout. Beurk !
Utiliser select() c'est une très vieille méthode. Pourquoi ne pas opter pour WSAEventSelect() ?
Et on vire tout le reste de la fonction. Il ne reste plus qu'à tester si on est connecté ou pas.
http://tangentsoft.net/wskfaq/
-- Cyrille Szymanski
> J'ai deux applications qui font un connect() sur une troisième qui fait un
accept() pour "ouvrir" la socket. Mon problème c'est que les deux accept() me
disent qu'ils sont connectés alors que la troisième application n'as fait
qu'un seul accept().
Je ne comprends pas vraiment. Comment accept() peut dire que les socket client
sont connectées ?
Et en plus la socket est configuré pour ne recevoir qu'une seule connexion (
listen( ..., 0) ).
Ça c'est le "backlog" (la taille de la file d'attente pour les demandes de
connexion *simultanées*)
Ce mélange unix/winsock est pas terrible. Avec winsock les types sont en
majuscules, les paramètres socket ne sont pas des int mais des SOCKET (qui sont
des entiers jusqu'à aujourd'hui).
SOCKET_ERROR est effectivement défini à (-1) mais c'est beaucoup mieux
d'utiliser la macro.
static int connectWithTimeout( s, name, namelen, timeout )
int s; /* socket descriptor */
SOCKET s;
struct sockaddr *name; /* adress of the socket to connect */
SOCKADDR *name;
int namelen; /* length of the socket, in bytes */
struct timeval *timeout; /* time-out value */
{
int on;
fd_set writefds;
int retval;
int peernamelen;
struct sockaddr peername;
SOCKARRD peername; /* note : n'est plus nécessaire */
/* put the socket s in non-blocking I/O mode to have the connect () */
/* return without pending */
on = 1;
ioctlsocket( s, FIONBIO, &on );
if ( connect( s, name, namelen ) < 0 )
== SOCKET_ERROR
{
errno = WSAGetLastError ();
/* when socket is set to non-blocking mode, connect () will return*/
/* with EINPROGRESS or EWOULDBLOCK if a connection cannot */
/* be setup immediatly */
Je ne suis pas certain que EINPROGRESS soit une erreur acceptable dans
ce contexte.
Les erreurs sont WSAE... : WSAEINPROGRESS et WSAEWOULDBLOCK.
if ( ( errno == EINPROGRESS ) || ( errno == EWOULDBLOCK ) )
{
/* we do synchronous polling on the write side of this socket */
/* using select() with the given <timeout> value until the */
/* connection gets established */
Sleep(10);
Ouh, pas beau du tout. Beurk !
Utiliser select() c'est une très vieille méthode. Pourquoi ne pas
opter pour WSAEventSelect() ?
> J'ai deux applications qui font un connect() sur une troisième qui fait un accept() pour "ouvrir" la socket. Mon problème c'est que les deux accept() me disent qu'ils sont connectés alors que la troisième application n'as fait qu'un seul accept().
Je ne comprends pas vraiment. Comment accept() peut dire que les socket client sont connectées ?
Et en plus la socket est configuré pour ne recevoir qu'une seule connexion ( listen( ..., 0) ).
Ça c'est le "backlog" (la taille de la file d'attente pour les demandes de connexion *simultanées*)
Ce mélange unix/winsock est pas terrible. Avec winsock les types sont en majuscules, les paramètres socket ne sont pas des int mais des SOCKET (qui sont des entiers jusqu'à aujourd'hui).
SOCKET_ERROR est effectivement défini à (-1) mais c'est beaucoup mieux d'utiliser la macro.
static int connectWithTimeout( s, name, namelen, timeout ) int s; /* socket descriptor */
SOCKET s;
struct sockaddr *name; /* adress of the socket to connect */
SOCKADDR *name;
int namelen; /* length of the socket, in bytes */ struct timeval *timeout; /* time-out value */ { int on; fd_set writefds; int retval; int peernamelen; struct sockaddr peername;
SOCKARRD peername; /* note : n'est plus nécessaire */
/* put the socket s in non-blocking I/O mode to have the connect () */ /* return without pending */
on = 1;
ioctlsocket( s, FIONBIO, &on );
if ( connect( s, name, namelen ) < 0 )
== SOCKET_ERROR
{ errno = WSAGetLastError ();
/* when socket is set to non-blocking mode, connect () will return*/ /* with EINPROGRESS or EWOULDBLOCK if a connection cannot */ /* be setup immediatly */
Je ne suis pas certain que EINPROGRESS soit une erreur acceptable dans ce contexte.
Les erreurs sont WSAE... : WSAEINPROGRESS et WSAEWOULDBLOCK.
if ( ( errno == EINPROGRESS ) || ( errno == EWOULDBLOCK ) ) { /* we do synchronous polling on the write side of this socket */ /* using select() with the given <timeout> value until the */ /* connection gets established */
Sleep(10);
Ouh, pas beau du tout. Beurk !
Utiliser select() c'est une très vieille méthode. Pourquoi ne pas opter pour WSAEventSelect() ?
Et on vire tout le reste de la fonction. Il ne reste plus qu'à tester si on est connecté ou pas.
http://tangentsoft.net/wskfaq/
-- Cyrille Szymanski
Sylvain Bénot
Cyrille Szymanski a écrit:
J'ai deux applications qui font un connect() sur une troisième qui fait un accept() pour "ouvrir" la socket. Mon problème c'est que les deux accept() me disent qu'ils sont connectés alors que la troisième application n'as fait qu'un seul accept().
Je ne comprends pas vraiment. Comment accept() peut dire que les socket client sont connectées ?
C'est une coquille, ce sont les connect() qui m'indique que la connexion a été acepté.
Et en plus la socket est configuré pour ne recevoir qu'une seule connexion ( listen( ..., 0) ).
Ça c'est le "backlog" (la taille de la file d'attente pour les demandes de connexion *simultanées*)
Ce que je voulais dire c'est que 1) la tache "serveur" n'attend qu'une connexion et 2) on est d'accord que si la tache "serveur" ne fait qu'un seul accept() il n'y a qu'un seul connect() qui peut réussir non ?
Ce mélange unix/winsock est pas terrible. Avec winsock les types sont en majuscules, les paramètres socket ne sont pas des int mais des SOCKET (qui sont des entiers jusqu'à aujourd'hui).
SOCKET_ERROR est effectivement défini à (-1) mais c'est beaucoup mieux d'utiliser la macro.
static int connectWithTimeout( s, name, namelen, timeout ) int s; /* socket descriptor */
SOCKET s;
struct sockaddr *name; /* adress of the socket to connect */
SOCKADDR *name;
int namelen; /* length of the socket, in bytes */ struct timeval *timeout; /* time-out value */ { int on; fd_set writefds; int retval; int peernamelen; struct sockaddr peername;
SOCKARRD peername; /* note : n'est plus nécessaire */
/* put the socket s in non-blocking I/O mode to have the connect () */ /* return without pending */
on = 1;
ioctlsocket( s, FIONBIO, &on );
if ( connect( s, name, namelen ) < 0 )
== SOCKET_ERROR
{ errno = WSAGetLastError ();
/* when socket is set to non-blocking mode, connect () will return*/ /* with EINPROGRESS or EWOULDBLOCK if a connection cannot */ /* be setup immediatly */
Je ne suis pas certain que EINPROGRESS soit une erreur acceptable dans ce contexte.
Les erreurs sont WSAE... : WSAEINPROGRESS et WSAEWOULDBLOCK.
if ( ( errno == EINPROGRESS ) || ( errno == EWOULDBLOCK ) ) { /* we do synchronous polling on the write side of this socket */ /* using select() with the given <timeout> value until the */ /* connection gets established */
Sleep(10);
Ouh, pas beau du tout. Beurk !
Utiliser select() c'est une très vieille méthode. Pourquoi ne pas opter pour WSAEventSelect() ?
Et on vire tout le reste de la fonction. Il ne reste plus qu'à tester si on est connecté ou pas.
http://tangentsoft.net/wskfaq/
Je suis d'accord avec toi c'est pas terrible mais j'ai pas le choix du code :(
Cyrille Szymanski a écrit:
J'ai deux applications qui font un connect() sur une troisième qui fait un
accept() pour "ouvrir" la socket. Mon problème c'est que les deux accept() me
disent qu'ils sont connectés alors que la troisième application n'as fait
qu'un seul accept().
Je ne comprends pas vraiment. Comment accept() peut dire que les socket client
sont connectées ?
C'est une coquille, ce sont les connect() qui m'indique que la connexion
a été acepté.
Et en plus la socket est configuré pour ne recevoir qu'une seule connexion (
listen( ..., 0) ).
Ça c'est le "backlog" (la taille de la file d'attente pour les demandes de
connexion *simultanées*)
Ce que je voulais dire c'est que 1) la tache "serveur" n'attend qu'une
connexion et 2) on est d'accord que si la tache "serveur" ne fait qu'un
seul accept() il n'y a qu'un seul connect() qui peut réussir non ?
Ce mélange unix/winsock est pas terrible. Avec winsock les types sont en
majuscules, les paramètres socket ne sont pas des int mais des SOCKET (qui sont
des entiers jusqu'à aujourd'hui).
SOCKET_ERROR est effectivement défini à (-1) mais c'est beaucoup mieux
d'utiliser la macro.
static int connectWithTimeout( s, name, namelen, timeout )
int s; /* socket descriptor */
SOCKET s;
struct sockaddr *name; /* adress of the socket to connect */
SOCKADDR *name;
int namelen; /* length of the socket, in bytes */
struct timeval *timeout; /* time-out value */
{
int on;
fd_set writefds;
int retval;
int peernamelen;
struct sockaddr peername;
SOCKARRD peername; /* note : n'est plus nécessaire */
/* put the socket s in non-blocking I/O mode to have the connect () */
/* return without pending */
on = 1;
ioctlsocket( s, FIONBIO, &on );
if ( connect( s, name, namelen ) < 0 )
== SOCKET_ERROR
{
errno = WSAGetLastError ();
/* when socket is set to non-blocking mode, connect () will return*/
/* with EINPROGRESS or EWOULDBLOCK if a connection cannot */
/* be setup immediatly */
Je ne suis pas certain que EINPROGRESS soit une erreur acceptable dans
ce contexte.
Les erreurs sont WSAE... : WSAEINPROGRESS et WSAEWOULDBLOCK.
if ( ( errno == EINPROGRESS ) || ( errno == EWOULDBLOCK ) )
{
/* we do synchronous polling on the write side of this socket */
/* using select() with the given <timeout> value until the */
/* connection gets established */
Sleep(10);
Ouh, pas beau du tout. Beurk !
Utiliser select() c'est une très vieille méthode. Pourquoi ne pas
opter pour WSAEventSelect() ?
J'ai deux applications qui font un connect() sur une troisième qui fait un accept() pour "ouvrir" la socket. Mon problème c'est que les deux accept() me disent qu'ils sont connectés alors que la troisième application n'as fait qu'un seul accept().
Je ne comprends pas vraiment. Comment accept() peut dire que les socket client sont connectées ?
C'est une coquille, ce sont les connect() qui m'indique que la connexion a été acepté.
Et en plus la socket est configuré pour ne recevoir qu'une seule connexion ( listen( ..., 0) ).
Ça c'est le "backlog" (la taille de la file d'attente pour les demandes de connexion *simultanées*)
Ce que je voulais dire c'est que 1) la tache "serveur" n'attend qu'une connexion et 2) on est d'accord que si la tache "serveur" ne fait qu'un seul accept() il n'y a qu'un seul connect() qui peut réussir non ?
Ce mélange unix/winsock est pas terrible. Avec winsock les types sont en majuscules, les paramètres socket ne sont pas des int mais des SOCKET (qui sont des entiers jusqu'à aujourd'hui).
SOCKET_ERROR est effectivement défini à (-1) mais c'est beaucoup mieux d'utiliser la macro.
static int connectWithTimeout( s, name, namelen, timeout ) int s; /* socket descriptor */
SOCKET s;
struct sockaddr *name; /* adress of the socket to connect */
SOCKADDR *name;
int namelen; /* length of the socket, in bytes */ struct timeval *timeout; /* time-out value */ { int on; fd_set writefds; int retval; int peernamelen; struct sockaddr peername;
SOCKARRD peername; /* note : n'est plus nécessaire */
/* put the socket s in non-blocking I/O mode to have the connect () */ /* return without pending */
on = 1;
ioctlsocket( s, FIONBIO, &on );
if ( connect( s, name, namelen ) < 0 )
== SOCKET_ERROR
{ errno = WSAGetLastError ();
/* when socket is set to non-blocking mode, connect () will return*/ /* with EINPROGRESS or EWOULDBLOCK if a connection cannot */ /* be setup immediatly */
Je ne suis pas certain que EINPROGRESS soit une erreur acceptable dans ce contexte.
Les erreurs sont WSAE... : WSAEINPROGRESS et WSAEWOULDBLOCK.
if ( ( errno == EINPROGRESS ) || ( errno == EWOULDBLOCK ) ) { /* we do synchronous polling on the write side of this socket */ /* using select() with the given <timeout> value until the */ /* connection gets established */
Sleep(10);
Ouh, pas beau du tout. Beurk !
Utiliser select() c'est une très vieille méthode. Pourquoi ne pas opter pour WSAEventSelect() ?
Et on vire tout le reste de la fonction. Il ne reste plus qu'à tester si on est connecté ou pas.
http://tangentsoft.net/wskfaq/
Je suis d'accord avec toi c'est pas terrible mais j'ai pas le choix du code :(
Cyrille Szymanski
On 2005-04-03, Sylvain Bénot wrote:
J'ai deux applications qui font un connect() sur une troisième qui fait un accept() pour "ouvrir" la socket. Mon problème c'est que les deux accept() me disent qu'ils sont connectés alors que la troisième application n'as fait qu'un seul accept().
Je ne comprends pas vraiment. Comment accept() peut dire que les socket client sont connectées ?
C'est une coquille, ce sont les connect() qui m'indique que la connexion a été acepté.
Ok, j'aurai du m'en rendre compte tout seul.
Normalement l'un des deux connect() renvoie 0 et l'autre SOCKET_ERROR. Est-ce bien le cas ? Je pense qu'il y a un problème avec les traitements qui sont faits quand la socket est non bloquante.
Ce que je voulais dire c'est que 1) la tache "serveur" n'attend qu'une connexion et 2) on est d'accord que si la tache "serveur" ne fait qu'un seul accept() il n'y a qu'un seul connect() qui peut réussir non ?
Exactement, même avec un backlog de 20, une seule connexion à la fois sera acceptée.
Utiliser select() c'est une très vieille méthode. Pourquoi ne pas opter pour WSAEventSelect() ?
Et on vire tout le reste de la fonction. Il ne reste plus qu'à tester si on est connecté ou pas.
http://tangentsoft.net/wskfaq/
Je suis d'accord avec toi c'est pas terrible mais j'ai pas le choix du code :(
Dans ce cas, garde le code BSD Socket dans un #ifdef et mets la version Winsock avec les WSAEventSelect() dans le #else. La fonction ioctl() tu la mets en macro aussi et ça rendra le code plus clair.
Cette histoire de tester le hostent est une bidouille et elle ne doit pas fonctionner de la même façon avec Winsock.
-- Cyrille Szymanski
On 2005-04-03, Sylvain Bénot <sylvain.benot@wanadoo.fr> wrote:
J'ai deux applications qui font un connect() sur une troisième qui fait un
accept() pour "ouvrir" la socket. Mon problème c'est que les deux accept() me
disent qu'ils sont connectés alors que la troisième application n'as fait
qu'un seul accept().
Je ne comprends pas vraiment. Comment accept() peut dire que les socket client
sont connectées ?
C'est une coquille, ce sont les connect() qui m'indique que la connexion
a été acepté.
Ok, j'aurai du m'en rendre compte tout seul.
Normalement l'un des deux connect() renvoie 0 et l'autre SOCKET_ERROR. Est-ce
bien le cas ? Je pense qu'il y a un problème avec les traitements qui sont
faits quand la socket est non bloquante.
Ce que je voulais dire c'est que 1) la tache "serveur" n'attend qu'une
connexion et 2) on est d'accord que si la tache "serveur" ne fait qu'un
seul accept() il n'y a qu'un seul connect() qui peut réussir non ?
Exactement, même avec un backlog de 20, une seule connexion à la fois sera
acceptée.
Utiliser select() c'est une très vieille méthode. Pourquoi ne pas
opter pour WSAEventSelect() ?
Et on vire tout le reste de la fonction. Il ne reste plus qu'à
tester si on est connecté ou pas.
http://tangentsoft.net/wskfaq/
Je suis d'accord avec toi c'est pas terrible mais j'ai pas le choix du
code :(
Dans ce cas, garde le code BSD Socket dans un #ifdef et mets la version
Winsock avec les WSAEventSelect() dans le #else. La fonction ioctl() tu
la mets en macro aussi et ça rendra le code plus clair.
Cette histoire de tester le hostent est une bidouille et elle ne doit pas
fonctionner de la même façon avec Winsock.
J'ai deux applications qui font un connect() sur une troisième qui fait un accept() pour "ouvrir" la socket. Mon problème c'est que les deux accept() me disent qu'ils sont connectés alors que la troisième application n'as fait qu'un seul accept().
Je ne comprends pas vraiment. Comment accept() peut dire que les socket client sont connectées ?
C'est une coquille, ce sont les connect() qui m'indique que la connexion a été acepté.
Ok, j'aurai du m'en rendre compte tout seul.
Normalement l'un des deux connect() renvoie 0 et l'autre SOCKET_ERROR. Est-ce bien le cas ? Je pense qu'il y a un problème avec les traitements qui sont faits quand la socket est non bloquante.
Ce que je voulais dire c'est que 1) la tache "serveur" n'attend qu'une connexion et 2) on est d'accord que si la tache "serveur" ne fait qu'un seul accept() il n'y a qu'un seul connect() qui peut réussir non ?
Exactement, même avec un backlog de 20, une seule connexion à la fois sera acceptée.
Utiliser select() c'est une très vieille méthode. Pourquoi ne pas opter pour WSAEventSelect() ?
Et on vire tout le reste de la fonction. Il ne reste plus qu'à tester si on est connecté ou pas.
http://tangentsoft.net/wskfaq/
Je suis d'accord avec toi c'est pas terrible mais j'ai pas le choix du code :(
Dans ce cas, garde le code BSD Socket dans un #ifdef et mets la version Winsock avec les WSAEventSelect() dans le #else. La fonction ioctl() tu la mets en macro aussi et ça rendra le code plus clair.
Cette histoire de tester le hostent est une bidouille et elle ne doit pas fonctionner de la même façon avec Winsock.
-- Cyrille Szymanski
Sylvain Bénot
Cyrille Szymanski a écrit:
On 2005-04-03, Sylvain Bénot wrote:
J'ai deux applications qui font un connect() sur une troisième qui fait un accept() pour "ouvrir" la socket. Mon problème c'est que les deux accept() me disent qu'ils sont connectés alors que la troisième application n'as fait qu'un seul accept().
Je ne comprends pas vraiment. Comment accept() peut dire que les socket client sont connectées ?
C'est une coquille, ce sont les connect() qui m'indique que la connexion a été acepté.
Ok, j'aurai du m'en rendre compte tout seul.
Normalement l'un des deux connect() renvoie 0 et l'autre SOCKET_ERROR. Est-ce bien le cas ? Je pense qu'il y a un problème avec les traitements qui sont faits quand la socket est non bloquante.
Pour ce que me souvient des tests que j'ai fait vendredi, les deux connect() commencent par me retourner SOCKET_ERROR avec EWOULDBLOCK comme code d'erreur et qu'ensuite avec le test du select() ça passe.
Ce que je voulais dire c'est que 1) la tache "serveur" n'attend qu'une connexion et 2) on est d'accord que si la tache "serveur" ne fait qu'un seul accept() il n'y a qu'un seul connect() qui peut réussir non ?
Exactement, même avec un backlog de 20, une seule connexion à la fois sera acceptée.
Utiliser select() c'est une très vieille méthode. Pourquoi ne pas opter pour WSAEventSelect() ?
Et on vire tout le reste de la fonction. Il ne reste plus qu'à tester si on est connecté ou pas.
http://tangentsoft.net/wskfaq/
Je suis d'accord avec toi c'est pas terrible mais j'ai pas le choix du code :(
Dans ce cas, garde le code BSD Socket dans un #ifdef et mets la version Winsock avec les WSAEventSelect() dans le #else. La fonction ioctl() tu la mets en macro aussi et ça rendra le code plus clair.
Cette histoire de tester le hostent est une bidouille et elle ne doit pas fonctionner de la même façon avec Winsock.
Je vais essayer la méthode WSA... pour voir s'il ça fonctionne mieux. Comment tu ferais pour tester ensuite si la socket est connecté ? Apparement l'histoire du getpeername() n'as pas l'air super !!
Merci
Sylvain
Cyrille Szymanski a écrit:
On 2005-04-03, Sylvain Bénot <sylvain.benot@wanadoo.fr> wrote:
J'ai deux applications qui font un connect() sur une troisième qui fait un
accept() pour "ouvrir" la socket. Mon problème c'est que les deux accept() me
disent qu'ils sont connectés alors que la troisième application n'as fait
qu'un seul accept().
Je ne comprends pas vraiment. Comment accept() peut dire que les socket client
sont connectées ?
C'est une coquille, ce sont les connect() qui m'indique que la connexion
a été acepté.
Ok, j'aurai du m'en rendre compte tout seul.
Normalement l'un des deux connect() renvoie 0 et l'autre SOCKET_ERROR. Est-ce
bien le cas ? Je pense qu'il y a un problème avec les traitements qui sont
faits quand la socket est non bloquante.
Pour ce que me souvient des tests que j'ai fait vendredi, les deux
connect() commencent par me retourner SOCKET_ERROR avec EWOULDBLOCK
comme code d'erreur et qu'ensuite avec le test du select() ça passe.
Ce que je voulais dire c'est que 1) la tache "serveur" n'attend qu'une
connexion et 2) on est d'accord que si la tache "serveur" ne fait qu'un
seul accept() il n'y a qu'un seul connect() qui peut réussir non ?
Exactement, même avec un backlog de 20, une seule connexion à la fois sera
acceptée.
Utiliser select() c'est une très vieille méthode. Pourquoi ne pas
opter pour WSAEventSelect() ?
Et on vire tout le reste de la fonction. Il ne reste plus qu'à
tester si on est connecté ou pas.
http://tangentsoft.net/wskfaq/
Je suis d'accord avec toi c'est pas terrible mais j'ai pas le choix du
code :(
Dans ce cas, garde le code BSD Socket dans un #ifdef et mets la version
Winsock avec les WSAEventSelect() dans le #else. La fonction ioctl() tu
la mets en macro aussi et ça rendra le code plus clair.
Cette histoire de tester le hostent est une bidouille et elle ne doit pas
fonctionner de la même façon avec Winsock.
Je vais essayer la méthode WSA... pour voir s'il ça fonctionne mieux.
Comment tu ferais pour tester ensuite si la socket est connecté ?
Apparement l'histoire du getpeername() n'as pas l'air super !!
J'ai deux applications qui font un connect() sur une troisième qui fait un accept() pour "ouvrir" la socket. Mon problème c'est que les deux accept() me disent qu'ils sont connectés alors que la troisième application n'as fait qu'un seul accept().
Je ne comprends pas vraiment. Comment accept() peut dire que les socket client sont connectées ?
C'est une coquille, ce sont les connect() qui m'indique que la connexion a été acepté.
Ok, j'aurai du m'en rendre compte tout seul.
Normalement l'un des deux connect() renvoie 0 et l'autre SOCKET_ERROR. Est-ce bien le cas ? Je pense qu'il y a un problème avec les traitements qui sont faits quand la socket est non bloquante.
Pour ce que me souvient des tests que j'ai fait vendredi, les deux connect() commencent par me retourner SOCKET_ERROR avec EWOULDBLOCK comme code d'erreur et qu'ensuite avec le test du select() ça passe.
Ce que je voulais dire c'est que 1) la tache "serveur" n'attend qu'une connexion et 2) on est d'accord que si la tache "serveur" ne fait qu'un seul accept() il n'y a qu'un seul connect() qui peut réussir non ?
Exactement, même avec un backlog de 20, une seule connexion à la fois sera acceptée.
Utiliser select() c'est une très vieille méthode. Pourquoi ne pas opter pour WSAEventSelect() ?
Et on vire tout le reste de la fonction. Il ne reste plus qu'à tester si on est connecté ou pas.
http://tangentsoft.net/wskfaq/
Je suis d'accord avec toi c'est pas terrible mais j'ai pas le choix du code :(
Dans ce cas, garde le code BSD Socket dans un #ifdef et mets la version Winsock avec les WSAEventSelect() dans le #else. La fonction ioctl() tu la mets en macro aussi et ça rendra le code plus clair.
Cette histoire de tester le hostent est une bidouille et elle ne doit pas fonctionner de la même façon avec Winsock.
Je vais essayer la méthode WSA... pour voir s'il ça fonctionne mieux. Comment tu ferais pour tester ensuite si la socket est connecté ? Apparement l'histoire du getpeername() n'as pas l'air super !!
Merci
Sylvain
Cyrille Szymanski
> Je vais essayer la méthode WSA... pour voir s'il ça fonctionne mieux. Comment tu ferais pour tester ensuite si la socket est connecté ? Apparement l'histoire du getpeername() n'as pas l'air super !!
Oui, c'est une bidouille.
Lis la doc de WSAAsyncEventSelect(), tu y trouveras notamment la phrase "An FD_WRITE network event is recorded when a socket is first connected with connect/WSAConnect or accepted with accept/WSAAccept" et d'autres infos qui te permettront de répondre aux questions que tu te poses.
A+ -- Cyrille Szymanski
> Je vais essayer la méthode WSA... pour voir s'il ça fonctionne mieux.
Comment tu ferais pour tester ensuite si la socket est connecté ?
Apparement l'histoire du getpeername() n'as pas l'air super !!
Oui, c'est une bidouille.
Lis la doc de WSAAsyncEventSelect(), tu y trouveras notamment la phrase "An
FD_WRITE network event is recorded when a socket is first connected with
connect/WSAConnect or accepted with accept/WSAAccept" et d'autres infos qui te
permettront de répondre aux questions que tu te poses.
> Je vais essayer la méthode WSA... pour voir s'il ça fonctionne mieux. Comment tu ferais pour tester ensuite si la socket est connecté ? Apparement l'histoire du getpeername() n'as pas l'air super !!
Oui, c'est une bidouille.
Lis la doc de WSAAsyncEventSelect(), tu y trouveras notamment la phrase "An FD_WRITE network event is recorded when a socket is first connected with connect/WSAConnect or accepted with accept/WSAAccept" et d'autres infos qui te permettront de répondre aux questions que tu te poses.
A+ -- Cyrille Szymanski
Sylvain Bénot
Cyrille Szymanski a écrit:
Je vais essayer la méthode WSA... pour voir s'il ça fonctionne mieux. Comment tu ferais pour tester ensuite si la socket est connecté ? Apparement l'histoire du getpeername() n'as pas l'air super !!
Oui, c'est une bidouille.
Lis la doc de WSAAsyncEventSelect(), tu y trouveras notamment la phrase "An FD_WRITE network event is recorded when a socket is first connected with connect/WSAConnect or accepted with accept/WSAAccept" et d'autres infos qui te permettront de répondre aux questions que tu te poses.
A+
J'ai écrit le code ci-dessous est ça fait toujours la même chose. Les deux connect() m'indique qu'il sont connecté à la même adresse même port alors que la tache "serveur" indique quelle n'as accepté qu'une seule connexion. J'ai refait le test en virant tout et en laissant juste l'appel à la fonction connect(), sans mettre les socket en non-bloquant et résultat identique. Je commence à me demander si le problème ne vient pas d'ailleur. Mais je ne vois pas où !!!
static int connectWithTimeout( s, name, namelen, timeout ) int s; /* socket descriptor */ struct sockaddr *name; /* adress of the socket to connect */ int namelen; /* length of the socket, in bytes */ struct timeval *timeout; /* time-out value */ { int on; int retval; WSAEVENT evtConnect; WSANETWORKEVENTS toto; DWORD result; int err;
Je vais essayer la méthode WSA... pour voir s'il ça fonctionne mieux.
Comment tu ferais pour tester ensuite si la socket est connecté ?
Apparement l'histoire du getpeername() n'as pas l'air super !!
Oui, c'est une bidouille.
Lis la doc de WSAAsyncEventSelect(), tu y trouveras notamment la phrase "An
FD_WRITE network event is recorded when a socket is first connected with
connect/WSAConnect or accepted with accept/WSAAccept" et d'autres infos qui te
permettront de répondre aux questions que tu te poses.
A+
J'ai écrit le code ci-dessous est ça fait toujours la même chose. Les
deux connect() m'indique qu'il sont connecté à la même adresse même port
alors que la tache "serveur" indique quelle n'as accepté qu'une seule
connexion. J'ai refait le test en virant tout et en laissant juste
l'appel à la fonction connect(), sans mettre les socket en non-bloquant
et résultat identique. Je commence à me demander si le problème ne vient
pas d'ailleur. Mais je ne vois pas où !!!
static int connectWithTimeout( s, name, namelen, timeout )
int s; /* socket descriptor */
struct sockaddr *name; /* adress of the socket to connect */
int namelen; /* length of the socket, in bytes */
struct timeval *timeout; /* time-out value */
{
int on;
int retval;
WSAEVENT evtConnect;
WSANETWORKEVENTS toto;
DWORD result;
int err;
Je vais essayer la méthode WSA... pour voir s'il ça fonctionne mieux. Comment tu ferais pour tester ensuite si la socket est connecté ? Apparement l'histoire du getpeername() n'as pas l'air super !!
Oui, c'est une bidouille.
Lis la doc de WSAAsyncEventSelect(), tu y trouveras notamment la phrase "An FD_WRITE network event is recorded when a socket is first connected with connect/WSAConnect or accepted with accept/WSAAccept" et d'autres infos qui te permettront de répondre aux questions que tu te poses.
A+
J'ai écrit le code ci-dessous est ça fait toujours la même chose. Les deux connect() m'indique qu'il sont connecté à la même adresse même port alors que la tache "serveur" indique quelle n'as accepté qu'une seule connexion. J'ai refait le test en virant tout et en laissant juste l'appel à la fonction connect(), sans mettre les socket en non-bloquant et résultat identique. Je commence à me demander si le problème ne vient pas d'ailleur. Mais je ne vois pas où !!!
static int connectWithTimeout( s, name, namelen, timeout ) int s; /* socket descriptor */ struct sockaddr *name; /* adress of the socket to connect */ int namelen; /* length of the socket, in bytes */ struct timeval *timeout; /* time-out value */ { int on; int retval; WSAEVENT evtConnect; WSANETWORKEVENTS toto; DWORD result; int err;