Browse Source

ft:添加tcp发送函数

master
lijie 1 year ago
parent
commit
327700f32c
1 changed files with 122 additions and 74 deletions
  1. +122
    -74
      src/misc/ntCom.erl

+ 122
- 74
src/misc/ntCom.erl View File

@ -4,115 +4,163 @@
-spec mergeOpts(Defaults :: list(), Options :: list()) -> list(). -spec mergeOpts(Defaults :: list(), Options :: list()) -> list().
mergeOpts(Defaults, Options) -> mergeOpts(Defaults, Options) ->
lists:foldl(
fun({Opt, Val}, Acc) ->
lists:keystore(Opt, 1, Acc, {Opt, Val});
(Opt, Acc) ->
lists:usort([Opt | Acc])
end,
Defaults, Options).
lists:foldl(
fun({Opt, Val}, Acc) ->
lists:keystore(Opt, 1, Acc, {Opt, Val});
(Opt, Acc) ->
lists:usort([Opt | Acc])
end,
Defaults, Options).
mergeAddr({Addr, _Port}, SockOpts) -> mergeAddr({Addr, _Port}, SockOpts) ->
lists:keystore(ip, 1, SockOpts, {ip, Addr});
lists:keystore(ip, 1, SockOpts, {ip, Addr});
mergeAddr(_Port, SockOpts) -> mergeAddr(_Port, SockOpts) ->
SockOpts.
SockOpts.
getPort({_Addr, Port}) -> Port; getPort({_Addr, Port}) -> Port;
getPort(Port) -> Port. getPort(Port) -> Port.
fixIpPort(IpOrStr, Port) -> fixIpPort(IpOrStr, Port) ->
if
is_list(IpOrStr), is_integer(Port) ->
{ok, IP} = inet:parse_address(v),
{IP, Port};
is_tuple(IpOrStr), is_integer(Port) ->
case isIpv4OrIpv6(IpOrStr) of
true ->
{IpOrStr, Port};
false ->
error({invalid_ip, IpOrStr})
end;
true ->
error({invalid_ip_port, IpOrStr, Port})
end.
if
is_list(IpOrStr), is_integer(Port) ->
{ok, IP} = inet:parse_address(v),
{IP, Port};
is_tuple(IpOrStr), is_integer(Port) ->
case isIpv4OrIpv6(IpOrStr) of
true ->
{IpOrStr, Port};
false ->
error({invalid_ip, IpOrStr})
end;
true ->
error({invalid_ip_port, IpOrStr, Port})
end.
parseAddr({Addr, Port}) when is_list(Addr), is_integer(Port) -> parseAddr({Addr, Port}) when is_list(Addr), is_integer(Port) ->
{ok, IPAddr} = inet:parse_address(Addr),
{IPAddr, Port};
{ok, IPAddr} = inet:parse_address(Addr),
{IPAddr, Port};
parseAddr({Addr, Port}) when is_tuple(Addr), is_integer(Port) -> parseAddr({Addr, Port}) when is_tuple(Addr), is_integer(Port) ->
case isIpv4OrIpv6(Addr) of
true ->
{Addr, Port};
false ->
error(invalid_ipaddr)
end;
case isIpv4OrIpv6(Addr) of
true ->
{Addr, Port};
false ->
error(invalid_ipaddr)
end;
parseAddr(Port) -> parseAddr(Port) ->
Port.
Port.
isIpv4OrIpv6({A, B, C, D}) -> isIpv4OrIpv6({A, B, C, D}) ->
A >= 0 andalso A =< 255 andalso
B >= 0 andalso B =< 255 andalso
C >= 0 andalso C =< 255 andalso
D >= 0 andalso D =< 255;
A >= 0 andalso A =< 255 andalso
B >= 0 andalso B =< 255 andalso
C >= 0 andalso C =< 255 andalso
D >= 0 andalso D =< 255;
isIpv4OrIpv6({A, B, C, D, E, F, G, H}) -> isIpv4OrIpv6({A, B, C, D, E, F, G, H}) ->
A >= 0 andalso A =< 65535 andalso
B >= 0 andalso B =< 65535 andalso
C >= 0 andalso C =< 65535 andalso
D >= 0 andalso D =< 65535 andalso
E >= 0 andalso E =< 65535 andalso
F >= 0 andalso F =< 65535 andalso
G >= 0 andalso G =< 65535 andalso
H >= 0 andalso H =< 65535;
A >= 0 andalso A =< 65535 andalso
B >= 0 andalso B =< 65535 andalso
C >= 0 andalso C =< 65535 andalso
D >= 0 andalso D =< 65535 andalso
E >= 0 andalso E =< 65535 andalso
F >= 0 andalso F =< 65535 andalso
G >= 0 andalso G =< 65535 andalso
H >= 0 andalso H =< 65535;
isIpv4OrIpv6(_) -> isIpv4OrIpv6(_) ->
false.
false.
%% @doc Return true if the value is an ipv4 address %% @doc Return true if the value is an ipv4 address
isIpv4({A, B, C, D}) -> isIpv4({A, B, C, D}) ->
A >= 0 andalso A =< 255 andalso
B >= 0 andalso B =< 255 andalso
C >= 0 andalso C =< 255 andalso
D >= 0 andalso D =< 255;
A >= 0 andalso A =< 255 andalso
B >= 0 andalso B =< 255 andalso
C >= 0 andalso C =< 255 andalso
D >= 0 andalso D =< 255;
isIpv4(_) -> isIpv4(_) ->
false.
false.
%% @doc Return true if the value is an ipv6 address %% @doc Return true if the value is an ipv6 address
isIpv6({A, B, C, D, E, F, G, H}) -> isIpv6({A, B, C, D, E, F, G, H}) ->
A >= 0 andalso A =< 65535 andalso
B >= 0 andalso B =< 65535 andalso
C >= 0 andalso C =< 65535 andalso
D >= 0 andalso D =< 65535 andalso
E >= 0 andalso E =< 65535 andalso
F >= 0 andalso F =< 65535 andalso
G >= 0 andalso G =< 65535 andalso
H >= 0 andalso H =< 65535;
A >= 0 andalso A =< 65535 andalso
B >= 0 andalso B =< 65535 andalso
C >= 0 andalso C =< 65535 andalso
D >= 0 andalso D =< 65535 andalso
E >= 0 andalso E =< 65535 andalso
F >= 0 andalso F =< 65535 andalso
G >= 0 andalso G =< 65535 andalso
H >= 0 andalso H =< 65535;
isIpv6(_) -> isIpv6(_) ->
false.
false.
gLV(Key, List, Default) -> gLV(Key, List, Default) ->
case lists:keyfind(Key, 1, List) of
false ->
Default;
{Key, Value} ->
Value
end.
case lists:keyfind(Key, 1, List) of
false ->
Default;
{Key, Value} ->
Value
end.
serverName(PoolName, Index) -> serverName(PoolName, Index) ->
list_to_atom(atom_to_list(PoolName) ++ "_" ++ integer_to_list(Index)).
list_to_atom(atom_to_list(PoolName) ++ "_" ++ integer_to_list(Index)).
asName(tcp, PrName) -> asName(tcp, PrName) ->
binary_to_atom(<<(atom_to_binary(PrName))/binary, "TAs">>);
binary_to_atom(<<(atom_to_binary(PrName))/binary, "TAs">>);
asName(ssl, PrName) -> asName(ssl, PrName) ->
binary_to_atom(<<(atom_to_binary(PrName))/binary, "SAs">>);
binary_to_atom(<<(atom_to_binary(PrName))/binary, "SAs">>);
asName(udp, PrName) -> asName(udp, PrName) ->
binary_to_atom(<<(atom_to_binary(PrName))/binary, "UOs">>).
binary_to_atom(<<(atom_to_binary(PrName))/binary, "UOs">>).
lsName(tcp, PrName) -> lsName(tcp, PrName) ->
binary_to_atom(<<(atom_to_binary(PrName))/binary, "TLs">>);
binary_to_atom(<<(atom_to_binary(PrName))/binary, "TLs">>);
lsName(ssl, PrName) -> lsName(ssl, PrName) ->
binary_to_atom(<<(atom_to_binary(PrName))/binary, "SLs">>);
binary_to_atom(<<(atom_to_binary(PrName))/binary, "SLs">>);
lsName(udp, PrName) -> lsName(udp, PrName) ->
binary_to_atom(<<(atom_to_binary(PrName))/binary, "URs">>).
binary_to_atom(<<(atom_to_binary(PrName))/binary, "URs">>).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% This is a generic "port_command" interface used by TCP, UDP, SCTP, depending
%% on the driver it is mapped to, and the "Data". It actually sends out data,--
%% NOT delegating this task to any back-end. For SCTP, this function MUST NOT
%% be called directly -- use "sendmsg" instead:
%%
syncSend(S, Data) ->
syncSend(S, Data, []).
syncSend(S, Data, OptList) when is_port(S), is_list(OptList) ->
MRef = monitor(port, S),
MRefBin = term_to_binary(MRef, [local]),
MRefBinSize = byte_size(MRefBin),
MRefBinSize = MRefBinSize band 16#FFFF,
try
erlang:port_command(S, [<<MRefBinSize:16, MRefBin/binary>>, Data], OptList)
of
false -> % Port busy when nosuspend option was passed
{error, busy};
true ->
receive
{inet_reply, S, Status, MRef} ->
demonitor(MRef, [flush]),
Status;
{'DOWN', MRef, _, _, _Reason} ->
{error, closed}
end
catch error: _ ->
{error, einval}
end.
asyncSend(S, Data) ->
asyncSend(S, Data, []).
asyncSend(S, Data, OptList) when is_port(S), is_list(OptList) ->
MRef = monitor(port, S),
MRefBin = term_to_binary(MRef, [local]),
MRefBinSize = byte_size(MRefBin),
MRefBinSize = MRefBinSize band 16#FFFF,
try
erlang:port_command(S, [<<MRefBinSize:16, MRefBin/binary>>, Data], OptList)
of
false -> % Port busy when nosuspend option was passed
{error, busy};
true ->
true
catch error: _ ->
{error, einval}
end.

Loading…
Cancel
Save