For c send function(blocking way) it's specified what function returns with size of sent bytes when it's received on destinations. I'm not sure that I understand all nuances, also after writing "demo" app with WSAIoctl and WSARecv on server side.
When send returns with less bytes number than asked in buffer-length parameter?
What is considered as "received on destinations"? My first guess it's when it sit on server's OS buffer and server application is notified. My second one it's when server application recv call have read it fully?
Unless you are using a (somewhat exotic) library, a send on a socket will return the number of bytes passed to the TCP buffer successfully, not the number of bytes received by the peer (see Microsoft´s docs for example).
When you are streaming data via a socket, you need to check the bytes effectively accepted into the TCP send buffer. That´s why usually a send command is inside a loop that will issue several sends if needed.
Errors in send are local: for example if the socket is closed by the peer during a sending operation (making your socket invalid) or if the operation times out (TCP buffer not emptying, i. e. peer not receiving data fast enough or some other trouble).
After all send is completed you have no easy way of knowing if the peer received all the bytes you sent. You´ll usually just issue closesocket and make sure that your socket has a proper linger option set (i. e. only close after timeout or sucessfully finishing the send). Alternatively you wait for a confirmation by the peer (for example via a recv that returns zero bytes, indicating that the connection was gracefully closed).
Edit: typo
I was trying to manipulate SOME/IP messages by falsifying their content(Payload) sent between 2 ECUs at run time.
After setting up the Hardware VN6510A MAC Bypassing and integrating it in the data traffic path between those 2 ECUs to monitor and control all Ethernet data streams.
ECU A ---> eth1 interface --VN6510A-- eth2 interface ---> ECU B
I successfully catch our target SOME/IP messages and I also succefully manipulate their paylod.
But at the end we got 2 SOME/IP messages: the real coming message and the falsified message forwarded at the same time.
How could we bound those 2 SOME/IP messages, the real message and the falsified message together, so that we could have just one falsified SOME/IP message, knowing that I am using the same SOME/IP message handle.
I used the callback function void OnEthPacket(LONG channel, LONG dir, LONG packet) to register a received Ethernet packet.
Probably by setting your VN.... to "Direct" and not "MAC Bypassing"
Well we could not manipulate Messages at run time using the vector box VN6510A Solution because simply their box doesn't support this feature.
I'm implementing a callback service for Asterisk queues.
The idea is to place all incoming calls on a queue. A message is played back, letting callers know that they can either wait in line until an agent becomes available or they can press '2', hangup, and have the agent call them back as soon as possible.
I defined a context for the inbound queue in queues.conf as such:
[qIngresoCC]
...
context=qIngresoCC-callback
...
and defined the corresponding entries in extensions.conf:
[qIngresoCC-callback]
exten = > 2,1,NoOp("El cliente ${CALLERID(all)} solicita CallBack")
same => n,AGI(add_channel_to_callback.php)
same => n,Playback(goodbye_for_the_best)
same => n,Hangup()
An incoming call is correctly sent to the queue, the announcements are played back, but when pressing '2', the call is not sent to the qIngresoCC-callback context.
DTMF logging is enabled, and I can see Asterisk receiving it, but it simply won't jump to the specified context.
[Jul 4 10:45:47] DTMF[84833][C-0000014d]: channel.c:4017 __ast_read: DTMF end '2' received on SIP/axtel-rappi-0000027b, duration 0 ms
[Jul 4 10:45:47] DTMF[84833][C-0000014d]: channel.c:4076 __ast_read: DTMF end accepted without begin '2' on SIP/axtel-rappi-0000027b
[Jul 4 10:45:47] DTMF[84833][C-0000014d]: channel.c:4087 __ast_read: DTMF end passthrough '2' on SIP/axtel-rappi-0000027b
What am I missing?
UPDATE
I forgot to specify:
I'm using Asterisk 13.14.0 compiled from source (by Portage) on Gentoo, with support (USE flags) for caps, curl, http, iconv, odbc, pjproject, postgres, samples, srtp.
I'm not using freepbx nor any other GUI. Everything is configured manually through the .conf files.
The only tuning of the source I did was changing channel.h from #define AST_MAX_ACCOUNT_CODE 20 to #define AST_MAX_ACCOUNT_CODE 256 to be able to use longer account codes.
The digit pressed must match the extension level in the context: for example if you have context=queue_out in your queues.conf and let's say your recording says "Press 5 to leave a voicemail (periodic announcement): extensions.conf would have the following
[queue_out]
exten => 5,1,Voicemail(123#default)
exten => 5,n,Hangup()
I had the same problem btw.
edited at 2015-11-25 02:10
My ejabberd version is 14.12 and erlang R17B, so this code seems not useful because erlang:system_info(otp_release) in R17B retruns "17"
ejabberd_listener.erl
SockOpts2 =
try erlang:system_info(otp_release) >= "R13B" of
true -> [{send_timeout_close, true} | SockOpts];
false -> SockOpts
catch
_:_ -> []
end,
I added {send_timeout_close, true} manually in listen option, my problem sees to be solved because socket is closed at the same time of send timeout, trying to send follow-up messages in the queue would receive a {error,enotconn} response.
when a {gen_event, 'closed'} msg comes, c2s process terminate normally.
edited at 2015-11-24 03:40
Maybe I found method to reproduce this problem:
1. build a normal c2s connection with xmpp client
2. cut the client's network with some tools, eg. clumsy(drops all the tcp packet from server)
3. keep sending large packets to the c2s process
At first, gen_tcp:send returns ok before sendbuffer fills
Then, gen_tcp:send retruns {error,timeout} because of sendbuffer is filled
the process calls ejabberd_socket:close(Socket) to close the connection
send_text(StateData, Text) when StateData#state.mgmt_state == active ->
catch ?INFO_MSG("Send XML on stream = ~ts", [Text]),
case catch (StateData#state.sockmod):send(StateData#state.socket, Text) of
{'EXIT', _} ->
(StateData#state.sockmod):close(StateData#state.socket),
error;
_ ->
ok
end;
But ejabberd_socket:close/1 seems to be an async call, so the c2s process would handle next message in message_queue, keep calling gen_tcp:send/2, waiting for a send_timeout.
But at this time, ejabberd_receiver called gen_tcp:close(Socket), the socket is closed, so previous gen_tcp:send/2 never returns. I have tried several times with this method, it happens 100%.
Briefly, if I send packets to a client socket which is unable to receive packet and the sendbuffer is fullfilled, i would receive a {error, timeout} after sendtimeout. But, if another async process closed the socket when i am waiting for a sendtimeout with gen_tcp:send/2, I would never get a response.
so, I did this with erl, and gen_tcp:send/2 no response ( cuting network at step3, keep sending packet, async close).
I want to know is this a problem or because reason of myself?
original post below
Generally in ejabberd , i route message to client process, send to tcp socket via this function. And it works well most time.
Module ejabberd_c2s.erl
send_text(StateData, Text) when StateData#state.mgmt_state == active ->
catch ?INFO_MSG("Send XML on stream = ~ts", [Text]),
case catch (StateData#state.sockmod):send(StateData#state.socket, Text) of
{'EXIT', _} ->
(StateData#state.sockmod):close(StateData#state.socket),
error;
_ ->
ok
end;
But in some cases the c2s pid blocked on gen_tcp:send like this
erlang:process_info(pid(0,8353,11)).
[{current_function,{prim_inet,send,3}},
{initial_call,{proc_lib,init_p,5}},
{status,waiting},
{message_queue_len,96},
{messages ...}
...
Most cases happened when user's network status not so good, the receiver process should send 2 messages to c2s pid , and c2s would terminate session or wait for resume
{'$gen_event',closed}
{'DOWN',#Ref<0.0.1201.250595>,process,<0.19617.245>,normal}
I printed message queue in the c2s process, the 2 msg are in the queue, waiting to be handled. Unfortunately,
the queue does not move any more becasue the process had blocked before handling these messages, as described above, stacked at prim_inet:send/3 when tring to do gen_tcp:send/2.
The queue grows very large after days, and ejabberd crahes when the process asking for more memory.
prim_inet:send/3 source :
send(S, Data, OptList) when is_port(S), is_list(OptList) ->
?DBG_FORMAT("prim_inet:send(~p, ~p)~n", [S,Data]),
try erlang:port_command(S, Data, OptList) of
false -> % Port busy and nosuspend option passed
?DBG_FORMAT("prim_inet:send() -> {error,busy}~n", []),
{error,busy};
true ->
receive
{inet_reply,S,Status} ->
?DBG_FORMAT("prim_inet:send() -> ~p~n", [Status]),
Status
end
catch
error:_Error ->
?DBG_FORMAT("prim_inet:send() -> {error,einval}~n", []),
{error,einval}
end.
It seems the port driver did not reply {inet_reply,S,Status} after erlang:port_command(S, Data, OptList) .
the gen_tcp:send function would block infinity, Can anyone explain this?
It depends on the version of Erlang you are using. The option to timeout on gen_tcp send is not used on old ejabberd version because it was not available at that time in Erlang. Moreover, you have to use a very recent version of Erlang as some bug were fixed in Erlang itself regarding that options.
I'm trying to upload videos to a server via TCP/IP using GCDAsyncSocket. Sometimes, the socket disconnects with an error that I haven't been able to eliminate:
2011-12-17 11:39:25.073 Hadza[433:707] socketDidDisconnect, error: Error Domain=NSPOSIXErrorDomain Code=12 "Cannot allocate memory" UserInfo=0x2aa260 {NSLocalizedFailureReason=Error in write() function, NSLocalizedDescription=Cannot allocate memory}
I've been looking everywhere but I can't really see what is the cause of this, how to fix it or workaround this issue.
The flow that the app follows to upload a file is the following:
Write to server (a media_id )
Read an ACK sign from server
Read number of bytes already sent
Write the video from bytes sent to the end
Read waiting for an ACK signal (meaning that the upload was ok)
If everything went OK , finish. If there was an error, restart from 1 or 3 depending on the error.