erlang:open_port

史研 419719104@REDACTED
Sat Jun 13 05:40:07 CEST 2020


Hi,


I'm sorry, my previous question is not clear.


I start a external process by erlang:open_port, and use two bytes for message length. But erlang process will not receive the message when the message's length of external process return is 10 bytes, and it will lead to all the follow messages can't be received. Using OTP 19.


This is how I'm using it:


%% erlang
init([Src]) ->
    erlang:process_flag(trap_exit, true),
    ServerId = erlang:integer_to_list(args_system:get_sid(Src)),
    Port = case os:type() of
               {win32, _} ->
                   open_port({spawn_executable, "./erlc_win32"}, [{packet, 2}, {args, [ServerId]}]);
               _ ->
                   open_port({spawn_executable, "./erlc_unix"}, [{packet, 2}, {args, [ServerId]}])
           end,
    {ok, #state{port = Port}}.



handle_call({call, Cmd, Msg}, From, #state{port = Port} = State) ->
    case call_encode(Cmd, From, Msg) of
        false ->
            {reply, false, State};
        Data ->
            Port ! {self(), {command, Data}},
            {noreply, State}
    end;
handle_call(_Request, _From, State) ->
    {reply, ok, State}.


handle_info({Port, {data, Data}}, #state{port = Port} = State) ->
    io:format("Len = ~p~n", [length(Data)]),
    case decode(Data) of
        {From, Msg} ->
            z_lib:reply(From, Msg);
        _ ->
            ok
    end,
    {noreply, State};
handle_info({'EXIT', Port, Reason}, #state{port = Port} = State) ->
    exit(Reason),
    {noreply, State};
handle_info(_Info, State) ->
    {noreply, State}.





// c
int main(int argc, char* argv[]) {

	int i;
	char out[1000] = {0};
	for(i = 0; i < 1000; ++i)
	{
		strcat(out, "|");
		write_cmd(out, strlen(out));
	}

}


int write_cmd(unsigned char* buf, int len)
{
	char li;
	li = (len >> 8) & 0xff;
	write_exact(&li, 1);
	li = len & 0xff;
	write_exact(&li, 1);
	return write_exact(buf, len);
}



int write_exact(unsigned char* buf, int len)
{
	int i, wrote = 0;
	while (wrote < len)
	{
		if ((i = write(1, buf + wrote, len - wrote)) <= 0) 
			return (i);
		wrote += i;
	}
	return(len);
}



See attachment for test result.


If I modify the write_cmd function as follows, it will runs correct.


int write_cmd(unsigned char* buf, int len)
{
	if ((len & 0xff) == 10)
	{
		len += 1;
	}
	char li;
	li = (len >> 8) & 0xff;
	write_exact(&li, 1);
	li = len & 0xff;
	write_exact(&li, 1);
	return write_exact(buf, len);
}
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20200613/580dd1bb/attachment.htm>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: result.png
Type: application/octet-stream
Size: 4308 bytes
Desc: not available
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20200613/580dd1bb/attachment.obj>


More information about the erlang-questions mailing list