Znovu FIFO a blokovani v open()

Pavel Kankovsky peak na argo.troja.mff.cuni.cz
Úterý Říjen 19 20:35:19 CEST 1999


On Tue, 19 Oct 1999, Michal Krause wrote:

> Socket je na tom relativne lepe, ale je to vyhoda pofiderni - az nejaky
> proces skonci s timeoutem, hned ho zastoupi jiny.

Da se udelat non-blocking connect a pak se taky da udelat to, ze jakmile
je pozitivne zjisteno, ze je demon tuhy, tak bude "resuscitovan" pomoci
volani kill() (no a pres sockety klienti dostanou v teto situaci jasne
najevo, ze nejsou vitani, protoze connect() selze).

> Myslel jsem, ze vliv na to, zda se connect blockne do timeoutu ma
> nastaveni backlogu (listen), ale budto to nechapu nebo to nefunguje.
> Predpokladal jsem, ze pokud bude backlog nastaven na hodnotu 1, muze byt
> jeden pozadavek resen, druhy ve fronte a tretimu by mel connect() vratit
> ECONNREFUSED. Nebo je to jinak?

Hmmm...ted s tim experimentuji a vypada to, ze aspon u unixovych se zadny
ECONNREFUSED nekona. Navic se mi podarilo vyloudit zajimavou vec: kdyz
klient zablokovany v connect() chcipne, tak accept() v serveru uspeje,
objevi se novy spojeny socket, ale nic se s nim neda delat. Budu muset
vyzkouset, jestli to delaji i jine verze nez 2.0.36. Pokud by to chtel
nekdo mermomoci zkouset, tak ma ty programky na konci. Staci prelozit a
dat server & klient & klient a pak promptne Ctrl+C.

--Pavel Kankovsky aka Peak  [ Boycott Microsoft--http://www.vcnet.com/bms ]
"Resistance is futile. Open your source code and prepare for assimilation."

<---klient--->
#include <unistd.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <stdio.h>
#include <stdlib.h>
 
void
check(int b, const char *m)
{
  if (b) {
    perror(m);
    exit(1);
  }
}
 
int
main()
{
  int s, x;
  struct sockaddr_un a;
  char b;
 
  s = socket(PF_UNIX, SOCK_STREAM, 0);
  check(s < 0, "socket");
  a.sun_family = AF_UNIX;
  strcpy(a.sun_path, "/tmp/pokusny_socket");
  x = connect(s, &a, sizeof(a));
  check(x < 0, "connect");
  b = 'x';
  x = write(s, &b, 1);
  check(x != 1, "write");
  x = read(s, &b, 1);
  check(x != 1, "read");
  shutdown(s, 2);
  close(s);
}
<---->

<---server--->
#include <unistd.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
 
void
check(int b, const char *m)
{
  if (b) {
    perror(m);
    exit(1);
  }
}
 
int
main()
{
  int s, t, x;
  struct sockaddr_un a;
  char b;
 
  s = socket(PF_UNIX, SOCK_STREAM, 0);
  check(s < 0, "socket");
  a.sun_family = AF_UNIX;
  strcpy(a.sun_path, "/tmp/pokusny_socket");
  x = unlink(a.sun_path);
  check(x < 0 && errno != ENOENT, "unlink");
  x = bind(s, &a, sizeof(a));
  check(x < 0, "bind");
  x = listen(s, 1);
  check(x < 0, "listen");
  for (;;) {
    t = accept(s, &a, &x);
    check(t < 0, "accept");
    x = read(t, &b, 1);
    check(x != 1, "read");
    sleep(5);
    x = write(t, &b, 1);
    check(x != 1, "write");
    shutdown(t, 2);
    close(t);
  }
}
<---->



Další informace o konferenci Linux