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...
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.
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.
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ä.
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.
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 lukemiseenrecv
:ta tairead
:ia socketille jaread
: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.
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 */ }
Voit lukea syötettä aivan hyvin vaikka merkki kerrallaan fgetc-funktiolla (getchar-makro). Mikä niitä estää laittamasta muistiin juuri niin kuin huvittaa?
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ä.
ircclient.c:(.text+0x17cf): undefined reference to `FD_CLEAR'
collect2: ld returned 1 exit status
tuollaista valittaa kääntäessä =/
Sen pitää olla FD_CLR
.
Aihe on jo aika vanha, joten et voi enää vastata siihen.