【问题标题】:Problems when debugging a socket-using program in C: connect在 C 中调试使用套接字的程序时出现的问题:connect
【发布时间】:2010-11-07 01:51:17
【问题描述】:

我正在使用 unix 套接字编写一个简单的客户端-服务器系统。从终端执行时,我的客户端程序会产生分段错误。

我很确定 seg-fault 是由一些菜鸟错误引起的,但是当我尝试使用 KDBG(kde gdb 前端)对其进行调试时,我的问题就出现了。

这就是它崩溃的地方:

 if (DEBUG) printf("-- connect()... \n");
 if (connect (mySocket, (struct sockaddr *)socketAddr,sizeof (*socketAddr)) == -1) {
  perror(error);
  printf("%s\n",error);
  printf ("-- Error when stablishing a connection\n");
  return -1;
 }

这是输出:

-- connect()... 
Connection refused

-- Error when stablishing a connection

我不能这样调试这段代码吗?为什么?

如果可以的话,你现在知道那里发生了什么吗?我应该怎么做才能获得更多信息?

PS: PS:@abelenky:这部分在调试器中完美运行。这是socketAddr的声明:

struct sockaddr_in socketAddr; 

... 

if ( (mySocket = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
    printf("Error al crear el socket\n"); 
    return -2; 
}

【问题讨论】:

  • 稳定?这是“建立”的一种形式吗?
  • 您应该描述您是如何创建 socketAddr 结构的,并提供证据证明您可以连接到可访问的服务器(即,没有防火墙或路由导致问题)
  • @abelensky - Yo por mi parte supongo que "jesusiniesta" es un hablante nativo del español, asi que cuando tu consigas escribir en su idioma al nivel que ha escrito en el tuyo, que sigas quejando .. . :P
  • @asveikau @abelensky :是的,我不是以英语为母语的人。事实上我真的很不擅长。但是当我犯了错误并尝试提高我的英语时,我可以知道。

标签: c debugging sockets kdbg


【解决方案1】:

这些函数需要一个字符串,而您正在向它们传递其他内容。

例如:

perror("socket");

虽然我从你的代码中不知道error 是在哪里声明的...也许你正在考虑全局变量errno,它是整数?

顺便说一句,perror 大致相当于这个:

void perror(const char *str)
{
    fprintf(stderr, "%s: %s\n", str, strerror(errno));
}

基于 cmets 更新:

在这种情况下,我的猜测是您还没有将 error 用于任何内容...我不确定您对 error 的期望是什么,但例如您可能想尝试一下:

snprintf(error, sizeof(error), "Error in %s:%d\n", __FILE__, __LINE__);
perror(error);

更新 2:

我想你想要这个:

if (connect (mySocket, (struct sockaddr *)&socketAddr, sizeof (socketAddr)) == -1) {

请注意,我在socketAddr 之前添加了&,并从sizeof 中删除了*

您如何进行主机名查找?我推荐getaddrinfo,例如:

struct addrinfo *res = NULL, hint;
char service[32];
int error;

snprintf(service, sizeof(service), "%d", port);

memset(&hint, 0, sizeof(hint));
hint.ai_socktype = SOCK_STREAM;

if ((error = getaddrinfo(host, service, &hint, &res)))
{
   fprintf(stderr, "No se pudo encontrar %s: %s\n", host, gai_strerror(error));
}
else
{
   fd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
   if (fd < 0)
   {
      perror("Error al crear el socket");
   }
   else if (connect(fd, res->ai_addr, res->ai_addrlen))
   {
      perror("Error al conexionar con el servidor");
      close(fd);
      fd = -1;
   }
}

if (res)
{
   freeaddrinfo(res);
}

这将让您从主机名和端口获取sockaddr,而无需关心 IPv4、IPv6 等。

【讨论】:

  • 现在我得到:socket.c:96 中的错误:连接被拒绝。那是errno 96吗?这意味着“不支持协议族”......但我现在不知道如何接受。
  • @jesusiniesta 96 是你文件的行号...我不知道你想放什么样的消息,但我只是想举个例子并解释不可打印的字符。
  • 至于为什么会出现“连接被拒绝”错误... 另一端没有服务器监听。你能说明socketAddr来自哪里吗?
  • 哎呀,这有多菜鸟?感谢您的输入,我不明白 perror 的正确用法。我已将 socketAddr 的声明放在第一篇文章中。它可以在调试器之外运行。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-08-27
  • 1970-01-01
  • 1970-01-01
  • 2020-02-21
  • 1970-01-01
相关资源
最近更新 更多