嵌入式技术论坛
直播中

而无返还

9年用户 1320经验值
擅长:光电显示
私信 关注
[问答]

使用实例程序时为什么会出现TCP无法连接的情况呢

使用时出现TCP无法连接的情况

当前LWIP已经能够跑起来,可以Ping通,但是是使用实例程序时出现TCP无法连接的情况,MSH输出的Log如下

tcpclient 192.168.1.9 50010
lwip_socket(PF_INET, SOCK_STREAM, 0) = 0
lwip_connect(0, addr=192.168.1.9 port=50010)
lwip_connect(0) failed, err=-4
Connect fail!
lwip_close(0)

其中192.168.1.9是我的PC,PC已使用网络助手开启了TCP Server,监听端口为50010,192.168.1.30为设备
使用PC的以ping命令Ping通:如下所示

Reply from 192.168.1.30: bytes=32 time=1ms TTL=255
Reply from 192.168.1.30: bytes=32 time<1ms TTL=255
Reply from 192.168.1.30: bytes=32 time<1ms TTL=255
Reply from 192.168.1.30: bytes=32 time=1ms TTL=255
Reply from 192.168.1.30: bytes=32 time=1ms TTL=255
Reply from 192.168.1.30: bytes=32 time=1ms TTL=255

TCP客户端示例如下

/*

Copyright (c) 2006-2018, RT-Thread Development Team

SPDX-License-Identifier: Apache-2.0

Change Logs:
Date Author Notes

/
/

程序清单:tcp 客户端

这是一个 tcp 客户端的例程
导出 tcpclient 命令到控制终端
命令调用格式:tcpclient URL PORT
URL:服务器地址 PORT::端口号
程序功能:接收并显示从服务端发送过来的信息,接收到开头是 'q' 或 'Q' 的信息退出程序
/
#include <rtthread.h>
#include <sys/socket.h> /
使用BSD socket,需要包含socket.h头文件 /
#include <netdb.h>
#include <string.h>
#include <finsh.h>
#define BUFSZ 1024
static const char send_data[] = "This is TCP Client from RT-Thread."; /
发送用到的数据 */
void tcpclient(int argc, char **argv)
{
int ret;
char *recv_data;
struct hostent *host;
int sock, bytes_received;
struct sockaddr_in server_addr;
const char url;
int port;
if (argc < 3)
{
rt_kprintf("Usage: tcpclient URL PORT
");
rt_kprintf("Like: tcpclient 192.168.1.9 50010
");
return ;
}
url = argv[1];
port = strtoul(argv[2], 0, 10);
/
通过函数入口参数url获得host地址(如果是域名,会做域名解析) /
host = gethostbyname(url);
/
分配用于存放接收数据的缓冲 /
recv_data = rt_malloc(BUFSZ);
if (recv_data == RT_NULL)
{
rt_kprintf("No memory
");
return;
}
/
创建一个socket,类型是SOCKET_STREAM,TCP类型 /
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1)
{
/
创建socket失败 /
rt_kprintf("Socket error
");
/
释放接收缓冲 /
rt_free(recv_data);
return;
}
/
初始化预连接的服务端地址 */
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(port);
server_addr.sin_addr = *((struct in_addr )host->h_addr);
rt_memset(&(server_addr.sin_zero), 0, sizeof(server_addr.sin_zero));
/
连接到服务端 */
if (connect(sock, (struct sockaddr )&server_addr, sizeof(struct sockaddr)) == -1)
{
/
连接失败 */
rt_kprintf("Connect fail!
");
closesocket(sock);
/*释放接收缓冲 /
rt_free(recv_data);
return;
}
while (1)
{
/
从sock连接中接收最大BUFSZ - 1字节数据 /
bytes_received = recv(sock, recv_data, BUFSZ - 1, 0);
if (bytes_received < 0)
{
/
接收失败,关闭这个连接 /
closesocket(sock);
rt_kprintf("
received error,close the socket.
");
/
释放接收缓冲 /
rt_free(recv_data);
break;
}
else if (bytes_received == 0)
{
/
默认 recv 为阻塞模式,此时收到0认为连接出错,关闭这个连接 /
closesocket(sock);
rt_kprintf("
received error,close the socket.
");
/
释放接收缓冲 /
rt_free(recv_data);
break;
}
/
有接收到数据,把末端清零 /
recv_data[bytes_received] = '\0';
if (strncmp(recv_data, "q", 1) == 0 || strncmp(recv_data, "Q", 1) == 0)
{
/
如果是首字母是q或Q,关闭这个连接 /
closesocket(sock);
rt_kprintf("
got a 'q' or 'Q',close the socket.
");
/
释放接收缓冲 /
rt_free(recv_data);
break;
}
else
{
/
在控制终端显示收到的数据 /
rt_kprintf("
Received data = %s ", recv_data);
}
/
发送数据到sock连接 /
ret = send(sock, send_data, strlen(send_data), 0);
if (ret < 0)
{
/
接收失败,关闭这个连接 /
closesocket(sock);
rt_kprintf("
send error,close the socket.
");
rt_free(recv_data);
break;
}
else if (ret == 0)
{
/
打印send函数返回值为0的警告信息 */
rt_kprintf("
Send warning,send function return 0.
");
}
}
return;
}
MSH_CMD_EXPORT(tcpclient, a tcp client sample);
经测试,不仅仅是TCP Client有问题,TCP Server和UDP都不能正常通信……

断点跟进,发现会进入到lwip_connect函数的这个句子"lwip_connect: invalid address"

LWIP_ERROR("lwip_connect: invalid address", IS_SOCK_ADDR_LEN_VALID(namelen) &&
IS_SOCK_ADDR_TYPE_VALID_OR_UNSPEC(name) && IS_SOCK_ADDR_ALIGNED(name),
sock_set_errno(sock, err_to_errno(ERR_ARG)); return -1;);
以下是 lwip_connect 函数

int
lwip_connect(int s, const struct sockaddr *name, socklen_t namelen)
{
struct lwip_sock sock;
err_t err;
sock = get_socket(s);
if (!sock) {
return -1;
}
if (!SOCK_ADDR_TYPE_MATCH_OR_UNSPEC(name, sock)) {
/
sockaddr does not match socket type (IPv4/IPv6) /
sock_set_errno(sock, err_to_errno(ERR_VAL));
return -1;
}
LWIP_UNUSED_ARG(namelen);
if (name->sa_family == AF_UNSPEC) {
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_connect(%d, AF_UNSPEC)
", s));
err = netconn_disconnect(sock->conn);
} else {
ip_addr_t remote_addr;
u16_t remote_port;
/
check size, family and alignment of 'name' /
LWIP_ERROR("lwip_connect: invalid address", IS_SOCK_ADDR_LEN_VALID(namelen) &&
IS_SOCK_ADDR_TYPE_VALID_OR_UNSPEC(name) && IS_SOCK_ADDR_ALIGNED(name),
sock_set_errno(sock, err_to_errno(ERR_ARG)); return -1;);
SOCKADDR_TO_IPADDR_PORT(name, &remote_addr, remote_port);
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_connect(%d, addr=", s));
ip_addr_debug_print_val(SOCKETS_DEBUG, remote_addr);
LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%"U16_F")
", remote_port));
#if LWIP_IPV4 && LWIP_IPV6
/
Dual-stack: Unmap IPv4 mapped IPv6 addresses /
if (IP_IS_V6_VAL(remote_addr) && ip6_addr_isipv4mappedipv6(ip_2_ip6(&remote_addr))) {
unmap_ipv4_mapped_ipv6(ip_2_ip4(&remote_addr), ip_2_ip6(&remote_addr));
IP_SET_TYPE_VAL(remote_addr, IPADDR_TYPE_V4);
}
#endif /
LWIP_IPV4 && LWIP_IPV6 */
err = netconn_connect(sock->conn, &remote_addr, remote_port);
}
if (err != ERR_OK) {
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_connect(%d) failed, err=%d
", s, err));
sock_set_errno(sock, err_to_errno(err));
return -1;
}
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_connect(%d) succeeded
", s));
sock_set_errno(sock, 0);
return 0;
}

请大神们指点迷津~

回帖(3)

李鑫

2023-1-9 17:13:32
wiznet
wiznet
软件后,发现更多帖子提示,电脑系统WIN10自带的防火墙关闭后就正常了。
举报

王莉

2023-1-9 17:13:43
ifconfig 看一下网页,以前也遇到过这种,好象和网页有关系
举报

王波

2023-1-9 17:13:54
防火墙进入站点规则设置一下,或者关闭防火墙。
举报

更多回帖

发帖
×
20
完善资料,
赚取积分