[MEGOLDVA] standard in/out TCP-re irányítása úgy, hogy előbb beírunk egy prefixet a TCP-be

Fórumok

Olyan parancssorra vagy szkriptre lenne szükségem, ami nyit egy TCP csatornát, beleír néhány előre megadott bájtot, majd a TCP csatornát "összeköti" az stdin/stdout-tal, azaz amit innen olvas, azt oda továbbítja, amit onnan olvas, azt ide továbbítja. Mást nem kell tudnia.

A probléma apropója ez a program: http://hup.hu/node/151733 SSH-n keresztül bejövő kapcsolatokat kötök hozzá egy csak belülről elérhető TCP porthoz. Az SSH a belül már titkosítatlan folyamot stdin és stdout-on keresztül adja át a kiszolgáló parancsnak, ami bármi lehet (szkript, program bármi ami futtatható). Tehát az stdin/stdout-ot kell egy TCP sockethez kötni. Ezt remekül meg lehet csinálni socat-tal. Valami ilyesmi a parancs (nem próbáltam):

socat - TCP4:example.com:8000

Az SSH szolgáltatás pont úgy működik, ahogy például a gitolite: http://gitolite.com/gitolite/glssh.html

Tehát a felhasználótól függően más és már argumentumokkal tudom indítani a kiszolgáló programot. Igenám, de az én kiszolgálóm TCP-n működik, és egy külön processz az, ami a streamet TCP-re továbbítja. Tehát a TCP csatornán kellene azt is közölni a szolgáltatással, hogy melyik felhasználó jelentkezett be. Ez egyszerű is lenne. A bejövő kapcsolathoz létrehozom a TCP kapcsolatot, beleírom a felhasználónevet (amit vesz a szerver), majd utána kapcsolom rá az stdin-t és stdout-ot a csatornára, mikor a szerver már tudja, hogy ki van a vonal végén. Mivel a szervert is én írom, ennek semmi akadálya nincs, és működik is.

A probléma csak annyi, hogy Java-ban megírva minden bejövő kapcsolat külön processze felzabál egy csomó RAM-ot, amit szeretnék megspórolni. Natív alkalmazást viszont lusta vagyok írni. Az az érzésem, hogy valahogy meg lehetne ezt oldani szkript+socat-tal, de nem jövök rá, hogy hogyan. Van erre valakinek tippje?

Szerk.:

A megoldás ez lett:


$ { echo lófütty ; cat ; } |socat - TCP4:localhost:9643

Ezzel ezek a processzek kezelnek egyetlen kapcsolatot (top kivágás):


31129 rcom 20 0 10732 1708 996 S 0,0 0,5 0:00.00 sshd
31130 rcom 20 0 6716 1388 1232 S 0,0 0,4 0:00.00 bash
31131 rcom 20 0 6720 668 504 S 0,0 0,2 0:00.00 bash
31132 rcom 20 0 4940 1332 1080 S 0,0 0,4 0:00.00 socat
31133 rcom 20 0 5684 568 496 S 0,0 0,2 0:00.00 cat

Azt ugyan nem értem, hogy miért van két bash processz, de egyelőre jó lesz :-).

Hozzászólások

Ezt a megoldást keresed?

echo "felhasználónév\n$(cat)" | ...

Ilyesmit, de ez nem tökéletes. Kipróbáltam parancssorban így:

$ echo "felhasználónév\n$(cat)"

Begépelek valamit, nyomok ctrl-d-t és valóban kiírja, hogy "felhasználónév\nalma\nkorte\nszolo"

Igenám, de csak a ctrl-d után. Nekem meg az kéne, hogy minden stream flush után azonnal írja a TCP-re, mivel egy kliens-szerver kommunikációs protokollnak kell működni. Vagy a flush is jól működne, csak valamiért terminálban nem olyan?

Szerintem ez elvileg nem jó, mivel a parancsértelmező futtatja a cat programot, és annak a kimenetét mint parancssori paramétert adja át az echo-nak miután a cat input stream lezárult. Tehát sztreamelésre nem alkalmas.

Ez működik, de nem értem, hogy miért :-). Az echo felhasználó kimenetét ráirányítjuk a cat-ra, eddig értem. De a - utána mit jelent? Ez nem a cat argumentuma, hanem a parancsértelmezőnek szól, és azt jelenti, hogy ha lejárt a kacsacsőrös input, akkor az stdin-ről folytassa?

Valami ilyesmi fog kelleni neked:

inditoszkript:

socat "TCP:$HOST:$PORT,connect-timeout=$TCP_CONNECT_TIMEOUT,forever,intervall=$TCP_RETRY_DELAY,crnl" "EXEC:$0-exec,pty,ctty,echo=0"


inditoszkript-exec:

chat -t "$TCP_CONNECT_TIMEOUT" -f chatscript || exit
exec /a/szerver/programod


chatscript:

ABORT 'Rejected'
'\-' 'username'
'Enter Password:' 'password'

(ezt hasznalom tavoli telefonkozpontok logjanak a lementesere, es elotte termeszetesen be kell jelentkezni)

szerk.: jut eszembe, ez a pelda azt feltetelezi, hogy a szerver programod stdin/stdout-on beszelget

Netcat jut eszembe elsőre, bár lehet nem sikerült felfognom, mi a cél.