【问题标题】:Weird Segmentation fault with Sockets in C with linux带有Linux的C中套接字的奇怪分段错误
【发布时间】:2020-07-13 13:37:55
【问题描述】:

目前我要做的只是为我尝试建立的简单客户端套接字连接修复此分段错误。我每次在 connect() 行都会遇到分段错误,我不知道为什么。我尝试了多种不同的实现来初始化所有要连接的东西,但都没有解决这个段错误。

这是 Client.C 代码:

/*LINUX socket initializations*/

#define DEFAULT_BUFLEN 512
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <arpa/inet.h> 
#include <errno.h>
int SendingSocket, portno;
struct hostent *server;
int iResult;
int iSendResult;
char recvbuf[DEFAULT_BUFLEN];
int recvbuflen = DEFAULT_BUFLEN;
char response[10];


#define DEFAULT_PORT "2212"
#define DEFAULT_ADDRESS "127.0.0.1"

int main(int argc, char* argv[];) {
/*
* Initializing socket 
*/

struct sockaddr_in serv_addr;

portno = atoi(DEFAULT_PORT);


SendingSocket = socket(AF_INET, SOCK_STREAM, 0);
if (SendingSocket < 0) 
    error("ERROR opening socket");
server = gethostbyname(DEFAULT_ADDRESS);
if (server == NULL) {
    fprintf(stderr,"ERROR, no such host\n");
    exit(0);
}

memset(&serv_addr, '0',sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(22041);

printf("got it\n");

in_addr_t in_addr = inet_addr("127.0.0.1");
if(INADDR_NONE == in_addr) {
perror("inet_addr() failed");
exit(0);
}
serv_addr.sin_addr.s_addr = in_addr;


if (connect(SendingSocket,(struct sockaddr *) &serv_addr,sizeof(serv_addr)) < 0) { 
    error("ERROR connecting");
}

printf("socket is connected!");


}
    /*
    * END socket initialization
    */

这是错误:

[asl@asl Bridge]$ ./socket
got it
./socket: Segmentation fault (core dumped)

这是 GDB 的输出:

/home/asl/Desktop/backup-4-1-20/Bridge/socket: 
Program received signal SIGSEGV, Segmentation fault.
strchrnul () at ../sysdeps/x86_64/strchrnul.S:34
34      movdqa  (%rdi), %xmm0

如果有帮助,我目前在 CentOS 6.8 环境中。

为什么这个奇怪的段错误来自 strchrnul?我无法从中找到任何信息。由于某些原因,我正在使用相当旧的操作系统...是否有需要更新的软件包或其他内容,或者这与我的代码有关?

编辑:这似乎是我的操作系统的软件包/某些东西的问题。这似乎不是我的代码的问题。我刚刚运行了这段代码,并在运行 raspbian 的树莓派上成功运行了它。任何人都知道 CentOS 中的问题可能是什么?

【问题讨论】:

  • 这看起来很可疑:memset(&amp;serv_addr, '0',sizeof(serv_addr));。也许你想要'\0' 或只是0
  • @ChristianGibbons 尝试了这两个选项并得到相同的错误:/
  • 发布您的完整代码。我怀疑您正在使用 send()/recv()/read()/write() 发送字符串并且未能解决您使用的函数不会终止字符串的事实。

标签: c linux sockets tcp centos


【解决方案1】:

您错误地使用了error()。根据手册页,该函数的格式为void error(int status, int errnum, const char *format, ...);,但您只是传递了一个字符串。也许您打算使用perror() 函数?

另外,如果不是复制错误,你有一个多余的分号:

int main(int argc, char* argv[];) {
                               ^

【讨论】:

  • 巧合的是,我刚刚发现这是问题所在,想寻求帮助和快速响应。
  • 只是一个关于您找到的解决方案的简短说明(我在您删除它之前看到了您的答案):根据我系统上的手册页,herror() 被认为已过时。不过,CentOS 6 已经很老了,所以它的库可能还没有淘汰它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-05-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多