unix domain socket, linux [ujabb problema]

 ( apal | 2010. augusztus 30., hétfő - 18:45 )

sziasztok!
problema a kovetkezo": adott egy unix domain socket (pl. /tmp/proba.sock), datagram tipussal. erre a socket-re kuld adatot egy masik program. az adat meg is erkezik. viszont az atvett cimet (amit a recvfrom() visszaad) mar nem lehet hasznalni az adat visszakuldesere. a kapcsolodo linux manual (`man 7 unix`) azt mondja, hogy alapjabanveve nincs gond ilyenkor mert a sun_path ekkor egy spe'ci erteket vesz fel allitolag, amire cimezve vissza lehet kuldeni az adatot. a speci ertek elso byte-ja 0, a tobbi meg hordozzza az infot. igy viszont nekem teszt-programokkal az jon le hogy a teljes sun_path marad 0 (elotte kinullaztam a rend kedveert, hogy ne stack-szeme't legyen benne). mit lehet tenni? internet (af_inet) eseten nincs problema ugye (tudjuk az udp gyakorlata'bol), ott a recvfrom()-ban a sin_port meg a sin_addr.s_addr megadja a portot meg az ip-szamot, es minden fasza. az rtfm viszont meg azt allitja hogy, de a gyakorlatban dehogy.
thx, a.

Hozzászólás megjelenítési lehetőségek

A választott hozzászólás megjelenítési mód a „Beállítás” gombbal rögzíthető.

Valamit elrontottal ;)
Ez nagy valoszinuseggel mukodik: http://docs.hp.com/en/B2355-90136/ch07s06.html

igen, ez igy mukodik, ezt tudom/probaltam. persze, ha vmi /tmp/random-ize.sock-hoz hozzako"to"m, akkor megy... de nem is ez volt a kerdes ;) a.

kivettem a HP-s kliensbol a bind-ot, es nekem valami szemet van a recvfrom() 'from'-jaba, a 'fromlen' pedig 0!
szerk.:
Sot Stevens bacsi is bind-olja a klienst (is).

igen, ez hogy nincs szeme't a from/peer-ben, az elegge linux-specifikusnak tunik. de linux alatt sem megy. na mindegy, az a baj hogy vannak egyeb furcsasagok is, lehet hogy atirom az egesz jatekot sock_stream-ra...

A klienst mindenkepp bind-olni kell, ha nem akarsz file-nevet, akkor johet az 'abstract' address igy:


address.sun_family = AF_UNIX;
address_length = sizeof(address.sun_family) + sprintf(address.sun_path, "#demo_socket");
address.sun_path[0] = 0;

bind(socket_fd, (struct sockaddr *) &address, address_length);

Es mindjart lesz 'fromlen' + minden...

ah. aha. ezt kiprobalom majd... koszi.

Holnap megnezem hogy az APUE mit ir rola.

igen, igy megy, fasza. koszi meg1x, igen, kell ez a ke'zi bind-elgetes, mindenkepp, me'gha ilyen hulye nevekre is.

Hat nem sokat segit :( , a DGRAM-ot nem is emliti kulon, de azert mond dolgokat es van pelda program is de az sem tartalmaz semmi ujdonsagot:

'This file exists only as a means of advertising the socket name to clients' a bind()-nek atadott path-rol es persze a programnak kell torolnie (unlink()).

Mashol arrol ir hogy a kliensnek kell sajat path-t valasztania, azert hogy a server meg tudja kulonboztetni a klienseket. Ez pedig lehet 'nyilvanos' egy letezo file-nevvel avagy kifele nem lathato
az 'abstract' path-szal.

Ha 'stream' típust használnál, akkor a fenti problémád magától megszűnne. Miért jó a 'datagram'?

az eredeti problemahoz kozelebb all a datagram (mikrokontrolleres ipv4 implementaciot tesztelgetek). valoban, meg lehet csinalni stream-mal is, sot, mas okok miatt (is) lehet hogy ez lesz belole, majd. mindenesetre az alap-problema is erdekesnek tunt, egy felvete'st mege'r ;] a.

uj kerdes (eredeti megoldva, lasd feljebb): datagram-ot csinalunk, ugye. viszont az tunt fel, hogy a sendto() hiaba kuld ki vmekkora (egybentartott) csomagot, a masik oldalon a recvfrom() csak egy kisebbet ad vissza. a levagas 256 byte-nal van. ez vajon mitol lehet? a datagram-kuldesnek elvileg pont ez lenne a lenyege, hogy a csomaghatarokat valtozatlanul hagyja:

... SOCK_DGRAM, for a datagram-oriented socket that preserves message boundaries (as on most Unix implementations, Unix domain datagram sockets are always reliable and don't reorder datagrams);

raadasul egymas utani sendto()-k tartalmat hajlamos osszevonni (pl kikuldok egymas utan rogton 292+292+284=868 byteot, erre megerkezik egy darab csomag, 3*256=768 bytetal)... vmit itt is benezek? socketpair()-ral ilyen gondok nem voltak, legalabbis meg 2-3 eve programozgattam ilyesmit oszt ott a datagrammoknal (1.5k-ig legalabbis) nem nyaszatolt.

a.

Ha egy iranyu gepen beluli adataramlas van, akkor a pipe-ot is nezd meg. Altalaban 4kB a max uzenetmeret, es tobben is irhatjak, nem keverednek az uzenetek. Bar nem ertem pontosan a helyezetedet...

ketiranyu, elegge, es ket kulon alkalmazas is fut, es nagyon message-orientalt (ip emulacio), szoval az unix domain datagram socket az idevago. igen, hogy 4k-nal kezdene levagni az me'g valahol ertheto" lenne, de 256 byte-nal...? ezt latom:

egyik progi ("szerver", aki letrehozza a fs-alatt is letezo" unix domain socket-et)

./tunsock: read from tun: 292
./tunsock: sendto(): 292
./tunsock: read from tun: 292
./tunsock: sendto(): 292
./tunsock: read from tun: 284
./tunsock: sendto(): 284

a masik (aki a fenti sendto()-kat fogatja):

recvfrom(): 768

vagy hasonloan:

./tunsock: read from tun: 260
./tunsock: sendto(): 260

ill:

recvfrom(): 256

uzenetkeveredes, ilyesmi nincs, csak 1-1 program beszelget.

szerk: raadasul ha a sendto() 256 v. annal kevesebbet kuld ki, akkor is hajlamos az osszeolvasztasra:

./tunsock: read from tun: 188
./tunsock: sendto(): 188
./tunsock: read from tun: 80
./tunsock: sendto(): 80

ill.

recvfrom(): 268