Просмотр исходного кода

fix: socket,accept函数应该返回对端ip和端口

https://gitee.com/openLuat/LuatOS/issues/ID3VYH
Wendal Chen 3 месяцев назад
Родитель
Сommit
86dd5d6a06

+ 28 - 5
components/network/adapter/luat_lib_socket.c

@@ -933,22 +933,26 @@ static int l_socket_wait(lua_State *L)
 作为服务端开始监听
 @api socket.listen(ctrl, multi_client)
 @user_data socket.create得到的ctrl
-@boolean multi_client 是否支持1对多客户端连接,true支持,false不支持,默认false不支持
+@int 等待accept的客户端数量, 默认0不支持, 取值范围0~8
 @return boolean true没有异常发生,false失败了,如果false则不需要看下一个返回值了,如果false,后续要close
 @return boolean true已经connect,false没有connect,之后需要接收socket.ON_LINE消息
 @usage 
 local succ, result = socket.listen(ctrl)
 -- 注意, 当目标适配器不支持1对多时,multi_client参数无效,并返回错误
+-- 注意, multi_client参数是可选的, 不传或者传0则表示单客户端模式
+-- multi_client 参数是 2025.11.10新增的, 之前的版本不支持
+local succ, result = socket.listen(ctrl, 8)
 */
 static int l_socket_listen(lua_State *L)
 {
 	luat_socket_ctrl_t *l_ctrl = l_get_ctrl(L, 1);
 	L_CTRL_CHECK;
-	if (lua_isboolean(L, 2))
+	if (lua_isinteger(L, 2))
 	{
-		l_ctrl->netc->listen_multi_client = lua_toboolean(L, 2);
-		if (!network_accept_enable(l_ctrl->netc))
+		l_ctrl->netc->max_wait_accept = lua_tointeger(L, 2);
+		if (!network_accept_enable(l_ctrl->netc) && l_ctrl->netc->max_wait_accept > 0)
 		{
+			l_ctrl->netc->max_wait_accept = 0;
 			LLOGE("目标适配器不支持1对多客户端连接模式");
 			lua_pushboolean(L, 0);
 			lua_pushboolean(L, 0);
@@ -959,7 +963,7 @@ static int l_socket_listen(lua_State *L)
 	lua_pushboolean(L, (result < 0)?0:1);
 	lua_pushboolean(L, result == 0);
 	if (result < 0) {
-		LLOGE("listen fail %d", result);
+		LLOGE("listen fail %d adapter %d port %d", result, l_ctrl->netc->adapter_index, l_ctrl->netc->local_port);
 	}
 	return 2;
 }
@@ -971,15 +975,22 @@ static int l_socket_listen(lua_State *L)
 @string or function or nil string为消息通知的taskName,function则为回调函数,和socket.create参数一致
 @return boolean true没有异常发生,false失败了,如果false则不需要看下一个返回值了,如果false,后续要close
 @return user_data or nil 如果支持1对多,则会返回新的ctrl,自动create,如果不支持则返回nil
+@return string 客户端ip, 2025.11.10新增
+@return int 客户端port, 2025.11.10新增
 @usage 
 local succ, new_netc = socket.accept(ctrl, cb)
 -- 注意, 当目标适配器不支持1对多时,new_netc会是nil, 第二个参数无效
 -- 当第二个参数为nil时, 固定为一对一模式, new_netc也会是nil
+
+-- 新增客户端ip和port返回值
+local succ, new_netc, client_ip, client_port = socket.accept(ctrl, "taskName")
+log.info("accept", succ, new_netc, client_ip, client_port)
 */
 static int l_socket_accept(lua_State *L)
 {
 	luat_socket_ctrl_t *old_ctrl = l_get_ctrl(L, 1);
 	if (!old_ctrl) return 0;
+	int result = 0;
 	if ((lua_isfunction(L, 2) || lua_isstring(L, 2)) && network_accept_enable(old_ctrl->netc))
 	{
 		luat_socket_ctrl_t *new_ctrl = (luat_socket_ctrl_t *)lua_newuserdata(L, sizeof(luat_socket_ctrl_t));
@@ -1035,13 +1046,25 @@ static int l_socket_accept(lua_State *L)
 		luaL_setmetatable(L, LUAT_NW_CTRL_TYPE);
 		lua_pushboolean(L, 1);
 		lua_pushvalue(L, -2);
+		#ifdef LUAT_USE_LWIP
+		lua_pushstring(L, ipaddr_ntoa(&new_ctrl->netc->remote_ip));
+		lua_pushinteger(L, new_ctrl->netc->remote_port);
+		return 4;
+		#else
 		return 2;
+		#endif
 	}
 	else
 	{
 		lua_pushboolean(L, !network_socket_accept(old_ctrl->netc, NULL));
 		lua_pushnil(L);
+		#ifdef LUAT_USE_LWIP
+		lua_pushstring(L, ipaddr_ntoa(&old_ctrl->netc->remote_ip));
+		lua_pushinteger(L, old_ctrl->netc->remote_port);
+		return 4;
+		#else
 		return 2;
+		#endif
 	}
 }
 

+ 4 - 3
components/network/adapter/luat_network_adapter.c

@@ -977,6 +977,9 @@ static int network_state_listen(network_ctrl_t *ctrl, OS_EVENT *event, network_a
 		break;
 	case EV_NW_SOCKET_NEW_CONNECT:
 	case EV_NW_SOCKET_CONNECT_OK:
+		if (ctrl->is_server_mode && ctrl->max_wait_accept > 0) {
+			return 0; // 对于多客户的tcpserver模式, 保持listen状态
+		}
 		ctrl->state = NW_STATE_ONLINE;
 		return 0;
 	default:
@@ -1659,9 +1662,6 @@ int network_socket_accept(network_ctrl_t *ctrl, network_ctrl_t *accept_ctrl)
 		accept_ctrl->local_port = ctrl->local_port;
 		accept_ctrl->state = NW_STATE_ONLINE;
 		DBG_ERR("accept_ctrl %p tag: %llu", accept_ctrl, accept_ctrl->tag);
-		// 将srv恢复到可接收的状态
-		ctrl->state = NW_STATE_LISTEN;
-		ctrl->wait_target_state = NW_WAIT_ON_LINE;
 		return 0;
 	}
 }
@@ -2209,6 +2209,7 @@ int network_listen(network_ctrl_t *ctrl, uint32_t timeout_ms)
 	}
 	if (ctrl->socket_id >= 0)
 	{
+		DBG("socket %d busy, state %d", ctrl->socket_id, ctrl->state);
 		return -1;
 	}
 	NW_LOCK;

+ 1 - 1
components/network/adapter/luat_network_adapter.h

@@ -210,7 +210,7 @@ typedef struct
     uint8_t state;
     uint8_t is_debug;
     uint8_t domain_ipv6;
-	uint8_t listen_multi_client; // 作为server时,是否支持一对多连接
+	uint8_t max_wait_accept; // 作为server时,最多支持多少个等待accept的客户端
 }network_ctrl_t;
 
 typedef struct

+ 3 - 2
olddemo/socket/tcp_server_mulit/tcpsrv.lua

@@ -22,11 +22,11 @@ local function serTask(port, adapter)
 	while true do
 		log.info("开始监听客户端连接, 无限时长")
 		-- sys.wait(1000)
-		result, code = libnet.listen(dName, 0, netc)
+		result, code = libnet.listen(dName, 0, netc, 8)  -- 支持最多8个等待accept的客户端
 		log.info("监听结果", result, code)
 		if result then
 			log.info("有客户端连接请求到来, 接受连接")
-            result, client = socket.accept(netc, function(client, event, param)
+            result, client, ip, port = socket.accept(netc, function(client, event, param)
 				log.info("客户端事件", client, event, params)
 				if event == socket.EVENT then
 					local result = socket.rx(client, buff)
@@ -34,6 +34,7 @@ local function serTask(port, adapter)
 					buff:seek(0)
 				end
 			end)
+			log.info("accept结果", result, client, ip, port)
 			socket.debug(client, true)
             if result then
 				table.insert(clients, client)