Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: C: sdl_net ongelmaa

Sivun loppuun

pienipoika [08.05.2008 19:09:17]

#

en ole aikaisemmin tehnyt socetteja joten tarvitsisin apua. sdl sovelluksessani toimii kaikki muu, paitsi datan sendaus ( SDLNet_TCP_Send() ). olen ottanut mallia sdl sivuilta löytämästäni linkistä jossa dokumentaatio kyseiselle kirjastolle. olen tehnyt juuri niinkuin ohjeessa sanotaan ja onnistuin muodostamaan socetin sekä vastaanottamaan dataa. kuitenkaan SDLNet_GetError() ei anna minkäänlaista virhettä datan lähetyksen jälkeen. myöskään wieshark:lla (verkonkuunteluohjelma) en lähettämiäni paketteja nähnyt. vain vastaanotetut. koodi siis kääntyy ilman erroreita/varoituksia ja ohjelmakaan ei anna virheitä.

mielessäni kävi tosiaan sellainen asia, että vika on tällä kertaa jossain muualla kuin koodissani. (alempana)

käytössäni on ubuntu gutsy (7.10) sekä gcc 4.1.3. SDL on versioltaan 1.2
dokumentaatiot joista olen ottanut mallia: http://jcatki.no-ip.org:8080/SDL_net/SDL_net_frame.html

olisin kiitollinen, jos joku voisi ystävällisesti auttaa minua ongelmassani.
kertokaa siis mitä vikaa koodissani on, miksi datan lähetys ei onnistu tai onke se mielestänne ihan validia ja vika toden näköisesti muualla.

tässä koodini:

//kiljubot.c
//käännän komennolla: gcc -o kiljubot kiljubot.c `sdl-config --cflags` `sdl-config --libs` -lSDL_net

#include <SDL/SDL.h>
#include <SDL/SDL_net.h>
#include <stdio.h>
#include <string.h>

int main (int argc, char *argv[]){

        //alustetaan SDL ja SDL_net
        if(SDL_Init(0)==-1) {
            printf("SDL_Init: %s\n", SDL_GetError());
            exit(0);
        }
        if(SDLNet_Init()==-1) {
            printf("SDLNet_Init: %s\n", SDLNet_GetError());
            exit(1);
        }

        //haetaan serverin ip ip muuttujaan ip
        IPaddress ip;

        if(SDLNet_ResolveHost(&ip, "tauri.ath.cx", 6667) < 0) {
                printf("SDLNet_ResolveHost: %s\n", SDLNet_GetError());
                exit(2);
        }

        //avataan socketti
        TCPsocket tcpsock;

        tcpsock=SDLNet_TCP_Open(&ip);
        if(!tcpsock) {
            printf("SDLNet_TCP_Open: %s\n", SDLNet_GetError());
            exit(3);
        }
        else printf("socketti avattu\n");

        //---------------
        //datan lähetys ja keräys

        int pituus, paluu;
        char puskuri[1024];

        char *user="USER kiljubot 0 0 :kiljubot\r\n";
        char *nick="NICK kiljubot\r\n";

        paluu=SDLNet_TCP_Recv(tcpsock, puskuri, 1024);
        if(paluu <= 0)
        printf("SDL_net: %s", SDLNet_GetError());
        else
        printf("vastaanotettu: %s\n", puskuri);

        paluu=SDLNet_TCP_Recv(tcpsock, puskuri, 1024);
        if(paluu <= 0)
        printf("SDL_net: %s", SDLNet_GetError());
        else
        printf("vastaanotettu: %s\n", puskuri);


        pituus=strlen(nick)+1;
        paluu=SDLNet_TCP_Send(tcpsock, nick, pituus);
        if(paluu < pituus)
        printf("SDL_net: %s", SDLNet_GetError());
        else
        printf("lähetetty: %s\n", nick);

        pituus=strlen(user)+1;
        paluu=SDLNet_TCP_Send(tcpsock, user, pituus);
        if(paluu < pituus)
        printf("SDL_net: %s", SDLNet_GetError());
        else
        printf("lähetetty: %s\n", user);

        paluu=SDLNet_TCP_Recv(tcpsock, puskuri, 1024);
        if(paluu <= 0)
        printf("SDL_net: %s", SDLNet_GetError());
        else
        printf("vastaanotettu: %s\n", puskuri);

        SDLNet_TCP_Close(tcpsock);

        SDLNet_Quit();
        SDL_Quit();
        return 0;
}
EOF.

älkää kiitos kritisoiko koodia muuten kuin selvistä virheitä jotka voivat aiheuttaa toimimattomuutta. tiedän ettei koodaustapani ole mikään paras enkä muutenkaan ole kummoinen tässä hommassa.

yllä oleva irc serveri on ystäväni eikä vaadi yhdistämisessä vastausta pingiin (ei edes pingaa) joten tuon ajettua ja nickin ja userin mennessä serverille kuuluisi serverin vastata mitä se ei minulla tee (koska ohjelma ei lähetä sinne mitään :() vastaukseksi tulee siis ping timeout.

ei sitten mennyt nuo sisennykset tuohon sivulle..

Mod. lisäsi kooditagit

Megant [08.05.2008 19:24:28]

#

printf("SDL_net: %s", SDLNet_GetError);

Tuossa ei kutsuta SDLNet_GetError-funktiota vaan annetaan sen osoite.

SDLNet_TCP_Send ja SDLNet_TCP_Recv ovat "blokkaavia" eli ohjelman suoritus ei jatku ennen kuin on saatu kaikki haluttu data lähetettyä tai vastaanotettua.
Esimerkiksi SDLNet_SocketReadyä käyttämällä näet pitäisikö socketista ottaa jotain tavaraa vastaan.

pienipoika [08.05.2008 19:28:00]

#

anteeksi. se on minulla koodissa printf("SDL_net: %s", SDLNet_GetError());
pahoittelen typosta. mutta jokatapauksessa en saa erroria. mtä minun pitäisi käytännössä tehdä ja miten sinä lähettäisit nuo kaksi pakettia?

"SDLNet_TCP_Send ja SDLNet_TCP_Recv ovat "blokkaavia" eli ohjelman suoritus ei jatku ennen kuin on saatu kaikki haluttu data lähetettyä tai vastaanotettua. "

mutta minulla ohjelma jatkuu send funktion jälkeen. eli ohjelma siis luulee että data on lähetetty vai..?

Megant [08.05.2008 19:41:27]

#

No siis, minulla ohjelma jää ainakin jumiin tuohon kohtaan jossa yritetään vastaanottaa dataa. (Alussa on kaksi SDLNet_TCP_Recv-kutsua)
Voit tehdä vaikka pääsilmukan, jossa katsotaan aina SDLNet_SocketReadyllä pitäisikö vastaanottaa jotain ja siihen sitten voitaisiin mennä vaikka kun on saatu lähetettyä nimimerkki ja yhdistyksessä olevat jutut.

pienipoika [08.05.2008 19:49:44]

#

koitit vai kääntää ohjelman? no siis 2 recv kutsua johtuu siitä, että kun kyseiselle irc-serverille connectaa, niin sieltä tulee 2 pakettia. sen jälkeen on aika lähettää dataa. (joka ei onnistukkaan). minulla ohjelma ei kyllä kaadu missään vaiheessa vaan loppuu kun ohjelma saa ping timeoutin. (koska data ei onnistuttu lähettämään).

tommosta mulla siis tulee:

nilast@Biff:~$ ./kiljubot
socketti avattu
vastaanotettu: :tauri.ath.cx NOTICE AUTH :*** Looking up your hostname...
vastaanotettu: :tauri.ath.cx NOTICE AUTH :*** Couldn't resolve your hostname; using your IP address instead
lähetetty: NICK kiljubot
lähetetty: USER kiljubot 0 0 :kiljubot
vastaanotettu: ERROR :Closing Link: kiljubot[88.192.167.194] (Ping timeout)
using your IP address instead

Megant [08.05.2008 20:11:22]

#

Kannattaa lukea lisää IRC-protokollasta vaikka RFC:stä.
Kun palvelin lähettää pingiviestin sille pitää vastata, tai muuten se katkaisee yhteyden.

pienipoika [08.05.2008 20:18:33]

#

juujuujuu. mä tiedän. mutta toi palvelin lähettää ekan ping viestin vasta kun client on onnistuneesti connectannu (mikä ei tossa ohjelmassa ikinä tapahdu) koita vaikka telnetillä tota hostia. mutta siis alkuperäseen ongelmaan:

-> miten on toi sendausfunktio? löytyykö koodista mitään kriittistä vikaa joka voi olla syynä sille, ettei datan lähetys onnistu? toimiiko toi ohjelma teillä?

Megant [08.05.2008 20:31:47]

#

pienipoika kirjoitti:

-> miten on toi sendausfunktio? löytyykö koodista mitään kriittistä vikaa joka voi olla syynä sille, ettei datan lähetys onnistu? toimiiko toi ohjelma teillä?

Kyllä se minulla saa lähetettyä, ainakin mitä netcatilla testailin.

pienipoika [08.05.2008 20:36:48]

#

20:35 [localhost] !tauri.ath.cx *** Notice -- Client connecting on port 6667: kiljubot (kiljubot@62.44.211.233) [clients]
20:35 [localhost] !tauri.ath.cx *** Notice -- Client exiting: kiljubot (kiljubot@62.44.211.233) [Connection reset by peer]

eli tuo olit siis sinä? ihme homma :OOO kiitos todella paljon. tästä oli apua, että tiedän nyt että vika ei tosiaan ole koodissa.. mutta missähän se vika sitten on :OO

haluaisitko megant vielä kertoa millä kääntäjällä ja millä sdl versiolla hoidit homman?
siis mikä on netcat? toimiko tuo minun koodini sellaisenaan?

Legu [08.05.2008 20:48:13]

#

Megant kirjoitti:

Kyllä se minulla saa lähetettyä, ainakin mitä netcatilla testailin.

Näin on. Lähetyksessä ei ole mitään vikaa, vaan vika on siinä, ettei ohjelma ilmeisesti (en nyt jaksanut tarkistaa) noudata IRC-protokollaa. Ohjelmasi toimii, kun ei lähetä nollatavuja komentojen loppuun:

//pituus=strlen(user)+1;
pituus = strlen(user);

pienipoika [08.05.2008 20:57:05]

#

Legu kirjoitti:

Näin on. Lähetyksessä ei ole mitään vikaa, vaan vika on siinä, ettei ohjelma ilmeisesti (en nyt jaksanut tarkistaa) noudata IRC-protokollaa. Ohjelmasi toimii, kun ei lähetä nollatavuja komentojen loppuun:

//pituus=strlen(user)+1;
pituus = strlen(user);

kiitos tästä ERITTÄIN paljon. otinpa sen nollatavun pois sieltä ja hyvin toimii minullakin :) kiitos kiitos.

pitääpä muistaa ettei seuraavan kerran luota sokeasti "viralliseen" dokumentaatioon: http://jcatki.no-ip.org:8080/SDL_net/SDL_net_frame.html (siitä kohta 3.3.5)
tuolta meinaa tota koodia kattelin..

noh. joka tapauksessa ongelma on nyt ratkaistu ja kiitän teitä hyvästä yhteistyöstä.

Legu [08.05.2008 22:53:14]

#

pienipoika kirjoitti:

pitääpä muistaa ettei seuraavan kerran luota sokeasti "viralliseen" dokumentaatioon: http://jcatki.no-ip.org:8080/SDL_net/SDL_net_frame.html (siitä kohta 3.3.5)
tuolta meinaa tota koodia kattelin..

Niin siis eihän tuossa mitään väärää ole. Se on vain esimerkki, joka näyttää SDLNet_TCP_Send -funktion toimintaa, eikä tuo mitenkään liity IRC:iin.

Vastaanottoesimerkissä vastaanotettu tavara tulostetaan sellaisenaan, joten jos nollatavua ei lähetettäisi, niin tapahtuisi ikäviä asioita. Tämän takia myös sinun koodissasi, kun palvelimelta nollatavua ei siis tule, saattaa esimerkiksi näkyä "ylimääräistä" tekstiä vastaanotettua tavaraa tulostettaessa. Ongelma korjaantuu lisäämällä nollatavu SDLNet_TCP_Recv -funktion palautusarvon osoittamaan paikkaan vastaanotetussa merkkijonossa.

On siis ihan käytettävästä toteutustavasta riippuvaista, että lähetetäänkö (ja vastaanotetaanko) nollatavu vai ei.


Sivun alkuun

Vastaus

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

Tietoa sivustosta