einval error when gen_tcp:recv after successful gen_tcp:send

Ericsson, Bjorn <>
Thu Dec 9 16:15:19 CET 2004


Hello!
 
This is my first week programming Erlang, so please be patient:
 
I'm trying to make an Erlang program that communicate over one open socket
by using gen_tcp. There is a server on the other end that I don't have any
control over, so I've also made a simulator for it in Erlang for the time
being. The server interface specifies that the client, my program, initiates
communication by sending a command, and then keeps the socket open and waits
for the server to reply. 
 
I have managed to get as far as my client sends a command, my server
simulator (run on same PC, but in other shell) receives that message and
sends a response, where gen_tcp:send returns ok. The problem arise when the
client tries to use gen_tcp:recv. This is where it receives {error, einval}.
 
How do you suggest I overcome this problem?
 
CLIENT CODE:
-module(interface).
-export([request/2]).
-include("interface.hrl").
 
request(Msisdn, Port) ->
%%% Build  request from input data %%%
   Request = build_request(Msisdn),
%%% Send request and wait for response %%%   
   Response = get_response(Request, Port),
   
build_request(Msisdn) ->
"0045006" ++ Msisdn ++ "46708998851FFFFFFFFF00".
 
get_response(Request, Port) ->
%%% Setup connection %%% 
  case gen_tcp:connect("localhost", Port,
                               [list, {packet, 0},{reuseaddr, true}]) of
    {ok, Sock} ->
    %%% Send request %%%               
        case gen_tcp:send(Sock, Request) of
            ok ->
                io:format("Message sent OK~n");
            {error, Reason} ->
                io:format("Send failed(~p)~n", [Reason])
        end,
    %%% Receive response %%%
        Response = receive_response(Sock),
        case gen_tcp:close(Sock) of
            ok ->
                io:format("Closing connection~n");
            {error, Reason2} ->
                io:format("Cannot close (~p)~n", [Reason2])
        end,
        Response;
    {error, Reason} ->
        io:format("Cannot connect to server (~p)~n", [Reason])
        % ToDo: handle this problem
  end.
  
receive_response(Sock) ->
    io:format("Sock (~p)~n", [Sock]),
    case gen_tcp:recv(Sock, 4) of
        {ok, B} ->
            Size = list_to_integer(B),
            io:format("Receiving message of size (~p).~n", [Size]);
        {error, Reason} ->
            Size = 0,
            io:format("Cannot receive Size (~p)~n", [Reason])
    end,
    case gen_tcp:recv(Sock, Size) of
        {ok, Message} ->
            io:format("Receiving message (~p).~n", [Message]),
            Message;
        {error, Reason2} ->
          io:format("Cannot receive (~p)~n", [Reason2])
    end.

SERVER SIMULATOR CODE:
-module(simulator).
-export([start/1]).
 
start(Port) ->
    case gen_tcp:listen(Port, [list, {packet, 0}, 
                  {active, false},{reuseaddr, true}]) of
      {ok, LSock} ->
        io:format("OK to listen~n"),
        case gen_tcp:accept(LSock) of
          {ok, Sock} ->
            io:format("OK to accept~n"),
            do_recv(Sock),
            send_response("46708797851FFFFFFFFF", Sock), 
            case gen_tcp:close(Sock) of
                ok ->
                    io:format("Closing connection~n");
                {error, Reason2} ->
                    io:format("Cannot close (~p)~n", [Reason2])
            end;
          {error, _} ->
            io:format("Cannot accept for server~n")
         end;     
      {error, Reason} ->
        io:format("Cannot listen for server (~p)~n", [Reason])
    end.
 
do_recv(Sock) ->
    io:format("Socket used (~p)~n", [Sock]),
    MessageSize = receive_size(Sock),
    Message = receive_message(Sock, MessageSize),
    io:format("Received message (~p)~n", [Message]),
    Message.
    
receive_size(Sock) ->
    case gen_tcp:recv(Sock, 4) of
        {ok, B} ->
            Size = list_to_integer(B),
            io:format("Receiving message of size (~p)~n", [Size]),
            Size;
        {error, Reason} ->
            io:format("Cannot receive (~p)~n", [Reason])
    end.
 
receive_message(Sock, MessageSize) ->
    case gen_tcp:recv(Sock, MessageSize) of
        {ok, Message} ->
            Message;
        {error, Reason} ->
            io:format("Cannot receive (~p)~n", [Reason])
    end.

send_response(Msisdn, Sock) ->
   Response = "0069009" ++ Msisdn ++ 
   "46708889951FFFFFFFFFNot Enough funds        08",
   case gen_tcp:send(Sock, Response) of
        ok ->
            io:format("Message sent (~p).~n", [Response]);
        {error, Reason} ->
            io:format("Cannot send (~p)~n", [Reason])
    end.



This e-mail and any attachment is for authorised use by the intended recipient(s) only. It may contain proprietary material, confidential information and/or be subject to legal privilege. It should not be copied, disclosed to, retained or used by, any other party. If you are not an intended recipient then please promptly delete this e-mail and any attachment and all copies and inform the sender. Thank you.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20041209/1bf84db3/attachment.html>


More information about the erlang-questions mailing list