Client/server Bad value on output port 'tcp_inet'
Per Bergqvist
per@REDACTED
Tue Feb 4 12:09:33 CET 2003
Hi,
It looks like you are trying to send a tuple. Don't.
/Per
> Hello fabulous Erlang guys
>
> I'm using OTP R9-0 on a Win32 platform (winsock) W2K and XP
>
> When I run a balanced client-server program ( attached below) the
connection phase is resolved with no problems.
> But the data exchange never happens due to some strange error I have
been chasing now for a week or so,
> -until now with no luck.... :-(
>
> in Desperation I loaded the program with debug outputs : All the
debug output give approx. this result on both sides when connecting
from 'knud2' to 'lhl-pc'
>
> accsocket init <0.72.0>,knud2 6000
> accsocket: gen_tcp:connect(knud2,6000),{packet, 0},{active, true }
> Connect error {reason,econnrefused}
> gen_tcp:listen (6000,[binary, {packet, 0}, {active,true}])
> ok,ListenSocket ListenSocket=#Port<0.118> info ={error,enotconn}
> runing initServer got Connect Socket #Port<0.119> Info
{ok,{{192,168,2,253},
> 6000}}
> GETACCTABLE Socket#socket.socket #Port<0.119> Data {[255,0,0,2]}
> accsocket:send(#Port<0.119>,{[255,0,0,2]})
> accsock:error Reasson einval
>
> =ERROR REPORT==== 4-Feb-2003::11:23:55 ===
> Bad value on output port 'tcp_inet'
>
> - the ERROR thing text is repeated for every data send attempt
>
>
> regards
> Software developer
> Lars H. Larsen
> ICCC A/S
> Måløvhovedgade 88
> 2760 Måløv
> Denmark
> http://www.iccc.dk
> mailto:lhl@REDACTED
> tel:+45 44860400
> GSM +45 51901320
>
>
> here is a printout of the program accsocket.erl, the real fun
happens in function socketLoop/1
>
> ========================================================== cut here
>
> -define(module, accsocket). % The name of
this module.
> -module(?module).
> -compile({module_info, [{identity, '@(#)AccSocket/R4A01'}]}).
>
> -author('LMDPLU@REDACTED').
>
> -export([socketLoop/1, init/3, initServer/3]).
>
>
>
>
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%
> %%%
> %%% Constants.
> %%%
>
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%
>
> % Definition of the alarm numbers used in the alarmlist.def file
> -define(alarmbase, 1500 ).
> -define(unknownMessageReceived, ?alarmbase+1 ).
> -define(accGwWentDown, ?alarmbase+31).
> -define(socketTransmissionError, ?alarmbase+32).
>
>
>
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%
> %%%
> %%% Records.
> %%%
>
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%
>
> -define(loopRecordName, socket).% To be used in the record
definition and in
> % the debug.hrl file.
>
> -record( ?loopRecordName,
> { socket = unknown, % The Socket reference.
> gwPid, % The Pid of the 'ACCGW' process.
> ipAddress, % The ip address of the socket
process.
> socketPort, % The socket port used to
communicate ...
> restData = [], % The Pid of the 'ACCGW' process.
> hostType, % The type of the socket connection
[server|client].
> logSocketCommand = #log{eventLevel=210,
eventString="ACCSOCKET: Command decoded: "},
> logSocketData = #log{eventLevel=210,
eventString="ACCSOCKET: SocketData received: "},
> logAlarm = #log{eventLevel=255,
eventString="ACCSOCKET Alarm: "}
> }).
>
>
>
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%
> %%%
> %%% Debug functions and records.
> %%%
>
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%
>
> -define(regName, 'ACCSOCKET'). % The registerred name.
> -include("debug.hrl").
>
>
>
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%
> %%
> %% Function : init/3
> %% Purpose : initiates the socket from the gateway.
> %% Args : Port - Variable containing the port number the gateway
will use for sockets
> %% Return : Spawns 2 processes, a client and a server.
> %%
>
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%
> init(GwPid, IpAddress, Port) when pid(GwPid), atom(IpAddress),
integer(Port)->
> io:fwrite("accsocket init ~p,~p ~p ~n",[GwPid, IpAddress,
Port]),
> process_flag(trap_exit, true),
> register(?regName, self()),
> %LHL socket:start(),
> initClientLoop(#socket{gwPid=GwPid, ipAddress=IpAddress,
socketPort=Port, hostType=client});
>
> init(_, _, _) ->
> io:fwrite("Bad parameter").
>
>
> initClientLoop(SocketRec)->
> timer:sleep(100), % Please don't ask why !
>
> io:format("accsocket: gen_tcp:connect(~w,~w),{packet, 0},{active,
true }~n",[SocketRec#socket.ipAddress, SocketRec#socket.socketPort]),
> case catch gen_tcp:connect(SocketRec#socket.ipAddress,
SocketRec#socket.socketPort, [binary,{packet,0},{active,true}]) of
> {error, _R} ->
> io:format("Connect error {reason,~w} ~n",[_R]),
> ServerPid = spawn_link(?module, initServer, [self(),
SocketRec#socket.ipAddress, SocketRec#socket.socketPort]),
> initServerLoop(SocketRec#socket{hostType=server}, ServerPid);
>
> {'EXIT', _Reason} ->
> io:format("Connect EXIT {reason,~w} ~n",[_Reason]),
> ServerPid = spawn_link(?module, initServer, [self(),
SocketRec#socket.ipAddress, SocketRec#socket.socketPort]),
> initServerLoop(SocketRec#socket{hostType=server}, ServerPid);
> {ok,Socket} ->
> io:format("runing initclient got Connect ~p ~n",[Socket]),
> SocketRec#socket.gwPid ! {'SOCKETSTATE',active},
> socketLoop(SocketRec#socket{socket = Socket})
>
> end.
>
> initServerLoop(SocketRec, ServerPid)->
> receive
>
> {'EXIT', ServerPid, Reason} ->
> io:format("{'EXIT', ServerPid, Reason}: ~p ~n",[Reason]),
> initClientLoop(SocketRec#socket{hostType=client});
>
> {'EXIT', GwPid, Reason} ->
> alarmmgr:notify(?accGwWentDown, [?MODULE, ?LINE, Reason]),
> log(SocketRec, logAlarm, {notify, ?accGwWentDown, ?MODULE, ?LINE,
[Reason]}),
> exit(Reason);
>
> {'ACCSOCKETCONNECT', ServerPid, Socket} ->
> SocketRec#socket.gwPid ! {'SOCKETSTATE', active},
> socketLoop(SocketRec#socket{socket = Socket});
>
> {'UPDATECODE', Module} ->
> unlink(ServerPid),
> exit(ServerPid, kill),
> case Module of
> ?module ->
> ?module:initClientLoop(SocketRec#socket{hostType=client});
> _Module ->
> initClientLoop(SocketRec#socket{hostType=client})
> end;
>
> {'SHUTDOWN', Pid} ->
> unlink(ServerPid),
> exit(ServerPid, kill),
> % io:fwrite(' SHUTDOWN request sent from ACCGW '),
> Pid ! {'SHUTDOWNOK',self()},
> initClientLoop(SocketRec#socket{hostType=client});
>
> %------------------------ Debug Functionallity
--------------------------%
>
> {getLoopData, Pid} ->
> Pid ! {loopData, SocketRec},
> initServerLoop(SocketRec, ServerPid);
>
> {logState, LogRecord, NewValue} ->
> NewSocketRec = logStateChange(SocketRec, LogRecord,
NewValue),
> initServerLoop(NewSocketRec, ServerPid);
>
> {logToScreen, LogRecord, NewValue} ->
> NewSocketRec = logToScreenChange(SocketRec, LogRecord,
NewValue),
> initServerLoop(NewSocketRec, ServerPid);
>
> {logLevel, LogRecord, NewValue} ->
> NewSocketRec = logLevelChange(SocketRec, LogRecord,
NewValue),
> initServerLoop(NewSocketRec, ServerPid);
>
> exit ->
> ok;
>
> Other ->
> io:format("SocketLoop Other: ~p ~n",[Other]),
> alarmmgr:notify(?unknownMessageReceived, [?MODULE,
?LINE, Other]),
> log(SocketRec, logAlarm, {notify,
?unknownMessageReceived, ?MODULE, ?LINE, [Other]}),
> initServerLoop(SocketRec, ServerPid)
>
> % after TimeOut ->
> % unlink(ServerPid),
> % exit(ServerPid, kill),
> % initClientLoop(SocketRec#socket{hostType=client})
>
> end.
>
> initServer(Initiator, IpAddress, Port)->
> %LHL ListenSocket = socket:listen('STREAM', 'AF_INET', Port,
{packet, 0}),
>
> io:format("gen_tcp:listen (~w,[binary, {packet, 0},
{active,true}])~n",[Port]),
>
> case catch gen_tcp:listen(Port,[binary, {packet, 0},
{active,true}]) of
> {error,Reason} ->
> io:format("Exit in listen (~w) ~n",[Reason]),
> exit(normal);
>
> {ok,ListenSocket} ->
> io:format("ok,ListenSocket ListenSocket=~p info
=~p~n",[ListenSocket,inet:peername(ListenSocket)]),
> case catch gen_tcp:accept(ListenSocket) of
> {error, Reason} ->
> io:format("Error gen_tcp:accept Reason~p ~n",[Reason]),
> %gen_tcp:close(ListenSocket),
> exit(normal);
>
> {ok,Socket}->
> io:format("runing initServer got Connect Socket ~p Info
~~p~n",[Socket,inet:sockname(Socket)]),
> Initiator ! {'ACCSOCKETCONNECT', self(), Socket},
> %LHL socket:controlling_process(Socket, Initiator),
> gen_tcp:controlling_process(Socket, Initiator),
> unlink(Initiator),
> gen_tcp:close(ListenSocket),
> ok
> end
> end.
>
>
>
>
>
>
>
>
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%
> %%
> %% Function : socketLoop/4
> %% Purpose : Loop that sends and receive data.
> %% Args : Socket - loop data
> %% Return : --
> %%
>
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%
>
> socketLoop(Socket) ->
> receive
> {tcp,SocketPid, SocketData} when SocketPid == Socket#socket.socket
->
> log(Socket, logSocketData, SocketData),
>
> io:format("Data from socket ~p~n",[SocketData]),
> case
accDecode(lists:flatten([Socket#socket.restData|SocketData])) of
> {reply, Data} ->
> log(Socket, logSocketCommand, {'NEWACCTABLE', Data}),
> Socket#socket.gwPid ! {'NEWACCTABLE', Data},
> socketLoop(Socket#socket{restData=[]});
>
> {request} ->
> log(Socket, logSocketCommand, {'GETACCTABLE'}),
> Socket#socket.gwPid ! {'GETACCTABLE'},
> socketLoop(Socket#socket{restData=[]});
>
> {splitData, {reply, Data}, RestData} ->
> log(Socket, logSocketCommand, [{'NEWACCTABLE', Data},
RestData]),
> Socket#socket.gwPid ! {'NEWACCTABLE', Data},
> socketLoop(Socket#socket{restData=RestData});
>
> {splitData, {request}, RestData} ->
> log(Socket, logSocketCommand, [{'GETACCTABLE'}, RestData]),
> Socket#socket.gwPid ! {'GETACCTABLE'},
> socketLoop(Socket#socket{restData=RestData});
>
> {packetNotEnded, RestData} ->
> socketLoop(Socket#socket{restData=RestData});
>
> {error, invalidPacket} ->
> alarmmgr:notify(?socketTransmissionError, [?MODULE, ?LINE,
[Socket#socket.restData|SocketData]]),
> log(Socket, logAlarm, {notify, ?socketTransmissionError,
?MODULE, ?LINE, [Socket#socket.restData|SocketData]}),
> socketLoop(Socket#socket{restData=[]})
>
> end;
>
> {tcp_closed,SocketPid} when SocketPid == Socket#socket.socket ->
> io:format("socket_closed,normal~n"),
> exit(normal);
>
> {tcp_error,SocketPid,Error} when SocketPid ==
Socket#socket.socket ->
> io:format("socket_closed,Error ~p~n",[Error]),
> exit(Error);
>
> {'GETACCTABLE'} ->
> Data= {[255, 0, 0, 2]},
> io:format("GETACCTABLE Socket#socket.socket ~p Data
~~p~n",[Socket#socket.socket,Data]),
> send(Socket#socket.socket,Data),
> % LHL Socket#socket.socket ! {self(),{deliver,[255, 0, 0, 2]}},
> socketLoop(Socket);
>
>
> {'NEWACCTABLE', Data} ->
> Data1 = accEncode(Data),
> io:format("NEWACCTABLE Socket#socket.socket ~p Data1
~~p~n",[Socket#socket.socket,Data1]),
> send(Socket#socket.socket,Data1),
> socketLoop(Socket);
>
> {'EXIT', Pid, Reason} when Pid == Socket#socket.gwPid ->
> alarmmgr:notify(?accGwWentDown, [?MODULE, ?LINE, Reason]),
> log(Socket, logAlarm, {notify, ?accGwWentDown, ?MODULE,
?LINE, [Reason]}),
> exit(Reason);
>
> {'UPDATECODE', ?module} ->
> ?module:socketLoop(Socket);
>
> {'UPDATECODE', Module} ->
> socketLoop(Socket);
>
> {'SHUTDOWN', Pid} ->
> % io:fwrite(' SHUTDOWN request sent from ACCGW '),
> Pid ! {'SHUTDOWNOK',self()},
> socketLoop(Socket);
>
> %------------------------ Debug Functionallity
--------------------------%
>
> {getLoopData, Pid} ->
> Pid ! {loopData, Socket},
> socketLoop(Socket);
>
> {logState, LogRecord, NewValue} ->
> NewSocket = logStateChange(Socket, LogRecord, NewValue),
> socketLoop(NewSocket);
>
> {logToScreen, LogRecord, NewValue} ->
> NewSocket = logToScreenChange(Socket, LogRecord, NewValue),
> socketLoop(NewSocket);
>
> {logLevel, LogRecord, NewValue} ->
> NewSocket = logLevelChange(Socket, LogRecord, NewValue),
> socketLoop(NewSocket);
>
> exit ->
> ok;
>
> Other ->
> alarmmgr:notify(?unknownMessageReceived, [?MODULE, ?LINE,
Other]),
> log(Socket, logAlarm, {notify, ?unknownMessageReceived,
?MODULE, ?LINE, [Other]}),
> socketLoop(Socket)
>
> end.
>
>
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%
> %%%
> %%% Function : accDecode/1
> %%%
> %%% Purpose : Checks and deocode the received packets from the other
call centre, and
> %%% sends them to Alternative Call Centre Gateway (ACCGW).
> %%%
> %%% Args : [255, Length1, Length2, Command | DataList] - The list,
which is received to be decoded.
> %%% 255 is a flag indicating start of the packet.
> %%% Lenght1 and Lenght2 are representing the total
> %%% lenght of the packet.
> %%% Command is type os the packet, which either is
> %%% 1 indicating "reply" or 2 indicating "request".
> %%% DataList is a list of tuples of Service Type and
> %%% the expected queuing time.
> %%% Return : error - The received packet is not valid.
> %%% {reply, decodeElements(DataList)} - "reply" is the type of
the packet,and the value of
> %%% decodeElements(DataList) is decoded received data.
> %%%
> %%% {request} - "request" is the type of the packet.
> %%%
> %%% {packetNotEnded, DataList} - "packetNotEnded" indicates that
the received packet is too short.
> %%%
> %%% {splitData, accDecode(NewDataList), RestData} - "splitData"
indicates the received packet had
>
> %%% been too long, and is splitet into "NewDataList"
> %%% and "RestData".
> %%%
>
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%
> accDecode([255,0,0,2]) ->
> {request};
>
> accDecode([255, Length1, Length2, 1 | DataList]) ->
> Length = (Length1 * 256) + Length2,
> case decodeList(Length, DataList) of
> packetOK ->
> {reply, decodeElements(DataList)};
> packetNotEnded ->
> {packetNotEnded, DataList};
> {packetTooLong, {NewDataList, RestData}} ->
> {splitData, accDecode(NewDataList), RestData}
> end;
>
> accDecode(_) ->
> {error, invalidPacket}.
>
>
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%
> %%%
> %%% Function : splitList/2
> %%%
> %%% Purpose : Split a list into two at a specified length.
> %%%
> %%% Args : List - The list, which is to be splitet into two.
> %%% Splitpoint - The number of enteries before splitting.
> %%%
> %%% Return : {FirstList, SecondList} - FirstList is the list before
the
> %%% split point. SecondList is the
> %%% remainder of the list after the split point.
> %%%
>
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%
> splitList(List, SplitPoint) ->
> splitList(List, SplitPoint, []).
>
> splitList([H | RestOfList], N, FirstList) when N > 0 ->
> splitList(RestOfList, N - 1, [H | FirstList]);
>
> splitList(SecondList, 0, FirstList) ->
> {lists:reverse(FirstList), SecondList}.
>
>
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%
> %%%
> %%% Function : decodeList/2
> %%%
> %%% Purpose : Checks the lenght of the data and call the split
fucntion, if the
> %%% data is too long.
> %%%
> %%% Args : Length - The total length of the data.
> %%%
> %%% Return : packetNotEnded - Indicates that the received packet is
too short.
> %%% {packetTooLong, splitList(DList, Length)} - "packetTooLong"
indicates
> %%% the list/data is too long,
> %%% and has to be splitet.
> %%%
>
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%
> decodeList(Length, DList) ->
> ListLength = length(DList),
> case Length of
> ListLength ->
> packetOK;
> N when N > ListLength ->
> packetNotEnded;
> _ ->
> {packetTooLong, splitList(DList, Length)}
> end.
>
>
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%
> %%%
> %%% Function : decodeElement/1
> %%%
> %%% Purpose : Decode the list into a list of tuples of two elements.
> %%%
> %%% Args : List - A flatten list.
> %%%
> %%% Return : Data - A list of tuples of Service Type and expected
queuing time..
> %%%
>
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%
> decodeElements([]) ->
> [];
>
> decodeElements([ServT1, ServT2, QT1, QT2 | Tail]) ->
> decodeElements([ServT1, ServT2, QT1, QT2 | Tail], []).
>
>
> decodeElements([ServT1, ServT2, QT1, QT2 | Tail], Data) ->
> NewData = [{ServT1 * 256 + ServT2, QT1 *256 + QT2} | Data],
> decodeElements(Tail, NewData);
>
> decodeElements([], Data) ->
> Data.
>
>
>
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%
> %%%
> %%% Function: accEncode/1 & /2
> %%%
> %%% Purpose : Encode the received OCC tuple to be a list of bytes
including
> %%% a start flag (255) length of data and 1 for request.
> %%%
> %%% Args : Data - A list of tuples to be encoded.
> %%%
> %%% Return : [255, 0, 0, 1] or [255, Length1, Length2, 1 |
EncodedData)]
> %%%
>
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%
> accEncode(Data) ->
> accEncode(Data, []).
>
> accEncode([], []) ->
> [255, 0, 0, 1];
>
> accEncode([], EncodedData) ->
> Length = length(EncodedData),
> Length1 = Length div 256,
> Length2 = Length rem 256,
> [255, Length1, Length2, 1 | EncodedData];
>
> accEncode([{ServiceType, QueueTime}|RestData], EncodedData) ->
> accEncode(RestData, [ServiceType div 256, ServiceType rem 256,
QueueTime div 256, QueueTime rem 256 | EncodedData]).
>
>
> send(Socket, Data)->
> io:format("accsocket:send(~p,~p)~n",[Socket,Data]),
> erlang:ports(),
> case gen_tcp:send(Socket, Data) of
> % Socket ! {self(), Data}.
> ok ->
> io:format("accsock:send-> ok~n"),
> ok;
>
> {error, Reason} ->
> s io:format("accsock:error Reasson ~p~n",[Reason]),
> erlang:ports(),
> exit(Reason)
> end.
>
>
>
>
=========================================================
Per Bergqvist
Synapse Systems AB
Phone: +46 709 686 685
Email: per@REDACTED
More information about the erlang-questions
mailing list