Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: C Irc-client

Sivun loppuun

tesmu [10.04.2006 18:34:34]

#

Eli aloin tässä vääntämään irc-clienttiä C kielellä(Linux). Vastaan tuli ongelma eli siis soketin osaan luoda ja yhdistää sekä lähettää tavaraa. Osaan myös recvaa dataa soketilla, mutta vastaan tuli tälläinen ongelma. Eli siis recvaan dataa tällätavalla. Soketti on fd

char buffer[1000];
while (1)
{
  if(state==-1) break;
  memset(buffer,'\0',sizeof(buffer));
  recv(fd, buffer, 1000, 0);
  state=parsedata(buffer, fd);
}

Mutta miten teen tuohon sillätavalla että voidaan kirjoittaa tekstiä samaanaikaan kun soketti ottaa dataa vastaan
jos esim pistän tuohon getsin niin soketti recvaa dataa ennen kuin painan entteriä etc...

Gaxx [10.04.2006 20:12:28]

#

Käytä säikeitä. Jos SDL on käytössä, vinkkiä toteutukseen voi katsoa täältä.

Luot erillisen säikeen datan vastaanottamista varten, jolloin blockiva recv-funktio ei häiritse muun ohjelman suoritusta.

A-P [10.04.2006 20:34:59]

#

Beej's Guide to Network Programming on hyvä perusopas socket-ohjelmointiin. Selectin käyttö voisi olla hyvä ratkaisu. Valinta selectin, forkin ja threadin välillä taitaa olla, tässä tapauksessa, loppujen lopuksi makuasia.

tesmu [10.04.2006 21:50:41]

#

Itseasiassa tässä pitää saada gets funktio ei blokkivaksi tjtnsp... recvin meinaan pitäis ottaa sillon dataa vastaan ku se saa sitä ilman että gets estää sitä.

koo [11.04.2006 00:20:55]

#

Ihan ekaksi: älä koskaan ikinä käytä funktiota gets, se on yksi historian pahimmista puskuriylivuotojen aiheuttajista. Toiseksi: seli seli, älä silti käytä sitä. :-)

Tässä taitaa olla yksinkertaisinta käyttää select-funktiota odottamaan, että olisi jotain luettavaa ja sitten lukemiseen recv:ta tai read:ia socketille ja read:ia stdinille.

Säikeillä asia kyllä onnistuu, mutta niiden kanssa homman hoitaminen oikein onkin sitten yllättävän vaikeaa.

tesmu [11.04.2006 12:07:57]

#

koo kirjoitti:

Ihan ekaksi: älä koskaan ikinä käytä funktiota gets, se on yksi historian pahimmista puskuriylivuotojen aiheuttajista. Toiseksi: seli seli, älä silti käytä sitä. :-)

Nytten se sitten selvisi miksi kääntäjä valittaa ettei getsiä pitäisi käyttää. =) Mutta siis kerro toinen tapa lukea syöte pointteriin.

koo kirjoitti:

Tässä taitaa olla yksinkertaisinta käyttää select-funktiota odottamaan, että olisi jotain luettavaa ja sitten lukemiseen recv:ta tai read:ia socketille ja read:ia stdinille.

Säikeillä asia kyllä onnistuu, mutta niiden kanssa homman hoitaminen oikein onkin sitten yllättävän vaikeaa.

En oikein sisäistänyt tuota selectiä että miten se toimii.

A-P [11.04.2006 12:41:49]

#

tesmu kirjoitti:

En oikein sisäistänyt tuota selectiä että miten se toimii.

Tämä on sitten testaamaton, joten siinä voi olla virheitä.

fd_set luku_fd;
FD_CLEAR(&luku_fd);
FD_SET(fd, &luku_fd);

struct timeval tv;
while (1) {
  tv.tv_sec=5;
  /* ensimmäinen parametri on suurin tiedostokahva+1 */
  select(fd+1, &luku_fd, NULL, NULL, &tv);

  if (FD_ISSET(fd, &luku_fd))
    recv;
  else
    ; /* jotain muuta */
}

Metabolix [11.04.2006 20:31:49]

#

Voit lukea syötettä aivan hyvin vaikka merkki kerrallaan fgetc-funktiolla (getchar-makro). Mikä niitä estää laittamasta muistiin juuri niin kuin huvittaa?

sooda [11.04.2006 20:59:16]

#

Tuossa A-P:n esimerkissä tulee todennäköisesti ongelmia. Muistaakseni leikin itsekin soketeilla joskus, ja selectin kanssa tuli juuri päänvaivaa. Tuo fd-setti pitää alustaa joka kerta ennen selectiä, koska select rikkoo sen, eli nuo koodin kolme ekaa riviä whilen sisään ennen selectiä.

tesmu [13.04.2006 17:57:59]

#

ircclient.c:(.text+0x17cf): undefined reference to `FD_CLEAR'
collect2: ld returned 1 exit status

tuollaista valittaa kääntäessä =/

koo [13.04.2006 19:41:50]

#

Sen pitää olla FD_CLR.


Sivun alkuun

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta