# Socket

**URL:** <https://www.ruby-forum.com/t/socket/149229>\
**Category:** IT\
**Created:** [September 22, 2008, 6:27pm UTC](https://www.ruby-forum.com/t/socket/149229 "2008-09-22T18:27:13Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![pixel75](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/9de053/32.png) [@pixel75](https://www.ruby-forum.com/u/pixel75)\
**Post date:** [September 22, 2008, 6:27pm UTC](https://www.ruby-forum.com/t/socket/149229/1 "2008-09-22T18:27:13Z")

</div>

Ciao a tutti,  
sto cercando di lavorare con i socket per realizzare una  
comunicazione SMPP.  
unica cosa Ã¨ che sembra che il socket si chiuda dopo la lettura.

mi spiego con un esempio:

```
 require 'socket'
 include Socket::Constants
 socket = Socket.new( AF_INET, SOCK_STREAM, 0 )
 sockaddr = Socket.pack_sockaddr_in( 80, 'www.google.com' )
 socket.connect( sockaddr )
 socket.write( "GET / HTTP/1.0\r\n\r\n" )
 results = socket.read

```

con questo leggo la pagina di google.

ma se volessi rileggerla usando lo stesso socket appena aperto?

rifacendo la reed mi torna 0

dove sbaglio?  
forse e troppo banale ma non vedo.

---

<div class="post-metadata">

**Author:** ![pixel75](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/9de053/32.png) [@pixel75](https://www.ruby-forum.com/u/pixel75)\
**Post date:** [September 22, 2008, 6:32pm UTC](https://www.ruby-forum.com/t/socket/149229/2 "2008-09-22T18:32:49Z")

</div>

Il Monday 22 September 2008 18:27:13 Dario P. ha scritto:

> ```
> sockaddr = Socket.pack_sockaddr_in( 80, 'www.google.com' )
> 
> ```
> 
> dove sbaglio?  
> forse e troppo banale ma non vedo.

sbagli candeggio con il protocollo.

HTTP 1.0 di default non supporta keepalive. quindi, devi creare una  
socket per  
ogni richiesta.

per ulteriori informazioni:

> **[404 Error - Page Not Found](https://www.ironmountain.com/data-centers/~maus/httpkeepalive.html)**
>
> 404 Error - Page Not Found

–  
Mauro T., Ph.D.  
Research Assistant

Distributed Systems Research Group  
Engineering Department  
University of Ferrara

---

<div class="post-metadata">

**Author:** ![pixel75](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/9de053/32.png) [@pixel75](https://www.ruby-forum.com/u/pixel75)\
**Post date:** [September 22, 2008, 7:13pm UTC](https://www.ruby-forum.com/t/socket/149229/3 "2008-09-22T19:13:22Z")

</div>

Il Monday 22 September 2008 18:40:27 Dario P. ha scritto:

> sockaddr = Socket.pack\_sockaddr\_in( 7004,“XXX.XXXXX.XXX”)  
> socket.connect( sockaddr )
> 
> @f = socket.write(@data)  
> d = socket.read
> 
> come posso continuare a scrivere e leggere dal socket?

mi dispiace, ma non conosco SMPP per cui non posso esserti molto utile.

comunque, a naso il tuo programma mi sembra corretto. ragion per cui, se  
fossi  
in te proverei a capire:

1. se effettivamente SMPP prevede che dopo l’invio di dati il client  
riceva  
una risposta. se così non fosse, allora il tuo programma funziona  
correttamente.
2. se qualcosa non va nella rete, sniffando i dati con wireshark

buon divertimento.

–  
Mauro T., Ph.D.  
Research Assistant

Distributed Systems Research Group  
Engineering Department  
University of Ferrara

---

<div class="post-metadata">

**Author:** ![pixel75](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/9de053/32.png) [@pixel75](https://www.ruby-forum.com/u/pixel75)\
**Post date:** [September 22, 2008, 6:40pm UTC](https://www.ruby-forum.com/t/socket/149229/4 "2008-09-22T18:40:27Z")

</div>

ok ma questo era un esempio… io devo implementare SMPP  
quindi ho una cosa del genere:

body = sprintf(“%s\0%s\0\0%c%c%c%s\0”, system\_id, password, 0x34,  
addr\_ton, addr\_npi, address\_range)  
length = 16 + body.length  
@data = fixed\_int(length) + fixed\_int(command\_id) + fixed\_int(0)+  
fixed\_int(next\_sequence\_number)+body

socket = Socket.new( AF\_INET, SOCK\_STREAM, 0 )  
sockaddr = Socket.pack\_sockaddr\_in( 7004,“XXX.XXXXX.XXX”)  
socket.connect( sockaddr )

@f = socket.write(@data)  
d = socket.read

come posso continuare a scrivere e leggere dal socket?

grazie mille.

Mauro T. wrote:

> Il Monday 22 September 2008 18:27:13 Dario P. ha scritto:
> 
> > ```
> > sockaddr = Socket.pack_sockaddr_in( 80, 'www.google.com' )
> > 
> > ```
> > 
> > dove sbaglio?  
> > forse e troppo banale ma non vedo.
> 
> sbagli candeggio con il protocollo.
> 
> HTTP 1.0 di default non supporta keepalive. quindi, devi creare una  
> socket per  
> ogni richiesta.
> 
> per ulteriori informazioni:
> 
> [404 Error - Page Not Found...](http://www.io.com/~maus/HttpKeepAlive.html)
> 
> –  
> Mauro T., Ph.D.  
> Research Assistant
> 
> Distributed Systems Research Group  
> Engineering Department  
> University of Ferrara

---

<div class="post-metadata">

**Author:** ![pixel75](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/9de053/32.png) [@pixel75](https://www.ruby-forum.com/u/pixel75)\
**Post date:** [September 22, 2008, 7:16pm UTC](https://www.ruby-forum.com/t/socket/149229/5 "2008-09-22T19:16:51Z")

</div>

tanto per dire io mi sono ispirato a questo PHP.

\<? /\* File: smppclass.php Implements: SMPPCLass() \*/ /\* The following are the SMPP PDU types that we are using in this class. Apart from the following 3 PDU types, there are a lot of SMPP directives that are not implemented in this version. \*/ define(CM\_BIND\_TRANSMITTER, 0x00000002); define(CM\_SUBMIT\_SM, 0x00000004); define(CM\_UNBIND, 0x00000006); class SMPPClass { // public members: /\* Constructor. Parameters: none. Example: $smpp = new SMPPClass(); \*/ function SMPPClass() { $this-\>\_socket = NULL; $this-\>\_command\_status = 0; $this-\>\_sequence\_number = 1; $this-\>\_source\_address = ""; } /\* For SMS gateways that support sender-ID branding, the method can be used to set the originating address. Parameters: $from : Originating address Example: $smpp-\>SetSender("31495595392"); \*/ function SetSender($from) { if (strlen($from) \> 20) { // todo echo "Error: sender id too long.\n"; return; } $this-\>\_source\_address = $from; } /\* This method initiates an SMPP session. It is to be called BEFORE using the Send() method. Parameters: $host : SMPP ip to connect to. $port : port # to connect to. $username : SMPP system ID $password : SMPP passord. $system\_type : SMPP System type Example: $smpp-\>Start("smpp.chimit.nl", 2345, "chimit", "my\_password", "client01"); \*/ function Start($host, $port, $username, $password, $system\_type) { $this-\>\_socket = fsockopen($host, $port, $errno, $errstr); // todo: sanity check on input parameters if (!$this-\>\_socket) { echo "Error opening SMPP session.\n"; echo "Error was: $errstr.\n"; return; } socket\_set\_timeout($this-\>\_socket, 1200); $status = $this-\>SendBindTransmitter($username, $password, $system\_type); if ($status != 0) { echo "Error binding to SMPP server. Invalid credentials?\n"; } } /\* This method sends out one SMS message. Parameters: $to : destination address. $text : text of message to send. Example: $smpp-\>Send("31495595392", "This is an SMPP Test message."); \*/ function Send($to, $text) { if (strlen($to) \> 20) { echo "to-address too long.\n"; return; } if (strlen($text) \> 160) { echo "Message too long.\n"; return; } if (!$this-\>\_socket) { // not connected return; } $service\_type = ""; $source\_addr\_ton = 0; $source\_addr\_npi = 0; $source\_addr = $this-\>\_source\_address; $dest\_addr\_ton = 1; $dest\_addr\_npi = 1; $destination\_addr = $to; $esm\_class = 0; $protocol\_id = 0; $priority\_flag = 0; $schedule\_delivery\_time = ""; $validity\_period = ""; $registered\_delivery\_flag = 0; $replace\_if\_present\_flag = 0; $data\_coding = 0; $sm\_default\_msg\_id = 0; $sm\_length = strlen($text); $short\_message = $text; $status = $this-\>SendSubmitSM($service\_type, $source\_addr\_ton, $source\_addr\_npi, $source\_addr, $dest\_addr\_ton, $dest\_addr\_npi, $destination\_addr, $esm\_class, $protocol\_id, $priority\_flag, $schedule\_delivery\_time, $validity\_period, $registered\_delivery\_flag, $replace\_if\_present\_flag, $data\_coding, $sm\_default\_msg\_id, $sm\_length, $short\_message); if ($status != 0) { echo "SMPP server returned error $status.\n"; } } /\* This method ends a SMPP session. Parameters: none Example: $smpp-\>End(); \*/ function End() { if (!$this-\>\_socket) { // not connected return; } $status = $this-\>SendUnbind(); if ($status != 0) { echo "SMPP Server returned error $status.\n"; } fclose($this-\>\_socket); $this-\>\_socket = NULL; } // private members (not documented): function ExpectPDU($our\_sequence\_number) { do { $elength = fread($this-\>\_socket, 4); extract(unpack("Nlength", $elength)); $stream = fread($this-\>\_socket, $length - 4); /\* echo "Read PDU : $length bytes.\n"; echo "Stream len : " . strlen($stream) . "\n"; \*/ extract(unpack("Ncommand\_id/Ncommand\_status/Nsequence\_number", $stream)); $command\_id &= 0x0fffffff; /\* echo "Command id : $command\_id.\n"; echo "Command status : $command\_status.\n"; echo "sequence\_number : $sequence\_number.\n"; \*/ switch ($command\_id) { case CM\_BIND\_TRANSMITTER: // echo "Got CM\_BIND\_TRANSMITTER\_RESP.\n"; break; case CM\_UNBIND: // echo "Got CM\_UNBIND\_RESP.\n"; break; case CM\_SUBMIT\_SM: // echo "Got CM\_SUBMIT\_SM\_RESP.\n"; break; default: // echo "Got unknown SMPP pdu.\n"; break; } } while ($sequence\_number != $our\_sequence\_number); return $command\_status; } function SendPDU($command\_id, $pdu) { $length = strlen($pdu) + 16; $header = pack("NNNN", $length, $command\_id, $this-\>\_command\_status, $this-\>\_sequence\_number); /\* echo "Sending PDU, len == $length\n"; echo "Sending PDU, header-len == " . strlen($header) . "\n"; echo "Sending PDU, command\_id == " . $command\_id . "\n"; \*/ fwrite($this-\>\_socket, $header . $pdu, $length); $status = $this-\>ExpectPDU($this-\>\_sequence\_number); $this-\>\_sequence\_number = $this-\>\_sequence\_number + 1; return $status; } function SendBindTransmitter($system\_id, $smpppassword, $system\_type) { $system\_id\_len = strlen($system\_id) + 1; $smpppassword\_len = strlen($smpppassword) + 1; $system\_type\_len = strlen($system\_type) + 1; $pdu = pack("a{$system\_id\_len}a{$smpppassword\_len}a{$system\_type\_len}CCCa1", $system\_id, $smpppassword, $system\_type, 3, 0, 0, ""); $status = $this-\>SendPDU(CM\_BIND\_TRANSMITTER, $pdu); return $status; } function SendUnbind() { $pdu = ""; $status = $this-\>SendPDU(CM\_UNBIND, $pdu); return status; } function SendSubmitSM($service\_type, $source\_addr\_ton, $source\_addr\_npi, $source\_addr, $dest\_addr\_ton, $dest\_addr\_npi, $destination\_addr, $esm\_class, $protocol\_id, $priority\_flag, $schedule\_delivery\_time, $validity\_period, $registered\_delivery\_flag, $replace\_if\_present\_flag, $data\_coding, $sm\_default\_msg\_id, $sm\_length, $short\_message) { $service\_type\_len = strlen($service\_type) + 1; $source\_addr\_len = strlen($source\_addr) + 1; $destination\_addr\_len = strlen($destination\_addr) + 1; $schedule\_delivery\_time\_len = strlen($schedule\_delivery\_time) + 1; $validity\_period\_len = strlen($validity\_period) + 1; $message\_len = $sm\_length + 1; // echo "PDU spec: a{$service\_type\_len}cca{$source\_addr\_len}cca{$destination\_addr\_len}ccca{$schedule\_delivery\_time\_len}a{$validity\_period\_len}ccccca{$message\_len}\n"; $pdu = pack("a{$service\_type\_len}cca{$source\_addr\_len}cca{$destination\_addr\_len}ccca{$schedule\_delivery\_time\_len}a{$validity\_period\_len}ccccca{$message\_len}", $service\_type, $source\_addr\_ton, $source\_addr\_npi, $source\_addr, $dest\_addr\_ton, $dest\_addr\_npi, $destination\_addr, $esm\_class, $protocol\_id, $priority\_flag, $schedule\_delivery\_time, $validity\_period, $registered\_delivery\_flag, $replace\_if\_present\_flag, $data\_coding, $sm\_default\_msg\_id, $sm\_length, $short\_message); $status = $this-\>SendPDU(CM\_SUBMIT\_SM, $pdu); return $status; } }; ?\>

e volevo semplicemente tradurlo in ruby  
Mauro T. wrote:

> Il Monday 22 September 2008 18:40:27 Dario P. ha scritto:
> 
> > sockaddr = Socket.pack\_sockaddr\_in( 7004,“XXX.XXXXX.XXX”)  
> > socket.connect( sockaddr )
> > 
> > @f = socket.write(@data)  
> > d = socket.read
> > 
> > come posso continuare a scrivere e leggere dal socket?
> 
> mi dispiace, ma non conosco SMPP per cui non posso esserti molto utile.
> 
> comunque, a naso il tuo programma mi sembra corretto. ragion per cui, se  
> fossi  
> in te proverei a capire:
> 
> 1. se effettivamente SMPP prevede che dopo l’invio di dati il client  
> riceva  
> una risposta. se cosï¿½ non fosse, allora il tuo programma funziona  
> correttamente.
> 2. se qualcosa non va nella rete, sniffando i dati con wireshark
> 
> buon divertimento.
> 
> –  
> Mauro T., Ph.D.  
> Research Assistant
> 
> Distributed Systems Research Group  
> Engineering Department  
> University of Ferrara
