隐式链接的 C 程序未连接到本地主机
Implicitly linked C Program is not connecting to localhost
我的实验哪里出了问题:
我正在尝试通过实验推断创建简单 shell 代码的细节。我的第一印象是我可能无法使用导入,因为我的 shell 代码没有被目标程序的编译器链接。然后我开始想知道我可以在不使用导入的情况下通过套接字创建一个简单的 shell 命令接口有多小,所以我写了一些代码;并开始忽略隐式调用警告:
// socket_family
#define AF_INET 2
#define AF_PACKET 17
// socket_type
#define SOCK_STREAM 1
typedef unsigned short sa_family_t;
struct sockaddr {
sa_family_t sa_family;
char sa_data[14];
};
struct in_addr {
unsigned long s_addr; // load with inet_pton()
};
struct sockaddr_in {
short sin_family; // e.g. AF_INET, AF_INET6
unsigned short sin_port; // e.g. htons(3490)
struct in_addr sin_addr; // see struct in_addr, above
char sin_zero[8]; // zero this if you want to
};
int main(void) {
int sfd;
const short family = AF_INET;
const char host[] = "127.0.0.1";
struct sockaddr addr;
struct sockaddr_in *addr_full = (struct sockaddr_in*)&addr;
if (sfd = socket(family, SOCK_STREAM, 0) < 0) return 1;
memset(&addr, 0, sizeof(struct sockaddr));
addr_full->sin_family = family;
addr_full->sin_port = htons(8000);
inet_pton(family, host, &(addr_full->sin_addr.s_addr));
if (connect(sfd, &addr, sizeof(struct sockaddr)) < 0) return 2;
close(sfd);
return 0;
}
沿线的某个地方我没有正确连接到我的 python -m SimpleHTTPServer
;报告 Serving HTTP on 0.0.0.0 port 8000
.
$ gcc my_program.c -o my_program
$ ./my_program
$ echo $?
2
我正在参加有关软件安全的 Coursera 课程;很多这个话题对我来说都是新的。
编辑:
删除重新定义并添加包括后:
#include <sys/socket.h>
#include <string.h>
#include <netinet/in.h>
int main(void) {
int sfd;
const short family = AF_INET;
const char host[] = "127.0.0.1";
struct sockaddr_in addr_full; // = (struct sockaddr_in*)&addr;
if (sfd = socket(family, SOCK_STREAM, 0) < 0) return 1;
memset(&addr_full, 0, sizeof(struct sockaddr));
addr_full.sin_family = family;
addr_full.sin_port = htons(8000);
inet_pton(family, host, &(addr_full.sin_addr.s_addr));
if (connect(sfd, (struct sockaddr*)&addr_full, sizeof(struct sockaddr)) < 0) return 2;
close(sfd);
return 0;
}
程序仍然以 2
退出。
您对包含文件的假设是错误的。包含文件只包含函数声明,不包含代码本身。他们不确定您的程序将如何链接到共享库。
包含文件只告诉编译器您在程序中调用的函数存在于某处,在某些外部库或您编写的另一个源文件中。编译后,链接器会尝试找到您的程序需要的所有函数,如果找不到,则链接失败。
尝试使用包含的必要文件(socket.h
等)编译您的代码。这会给你有用的警告,例如当你传递错误类型的参数时。
未正确分配套接字文件描述符。添加括号,我应该分配描述符,然后检查它的值:
if ((sfd = socket(family, SOCK_STREAM, 0)) < 0) return 1;
本子,
请获取 C
语言书籍并检查操作优先级。并经常这样做,即使是经验丰富的开发人员也会在这里犯错误。并且不要写这种疯狂的风格,请学习如何为人类写作:
if (sfd = socket(family, SOCK_STREAM, 0) < 0) return 1;
你应该这样做:
sfd = socket(family, SOCK_STREAM, 0);
if (sfd < 0)
{
/* perror() is pretty old style but some good check is recommended. */
perror("socket");
return 1;
}
剧透:<
在这里具有更高的优先级,因此 sfd
在您的代码中始终为 0。
我的实验哪里出了问题:
我正在尝试通过实验推断创建简单 shell 代码的细节。我的第一印象是我可能无法使用导入,因为我的 shell 代码没有被目标程序的编译器链接。然后我开始想知道我可以在不使用导入的情况下通过套接字创建一个简单的 shell 命令接口有多小,所以我写了一些代码;并开始忽略隐式调用警告:
// socket_family
#define AF_INET 2
#define AF_PACKET 17
// socket_type
#define SOCK_STREAM 1
typedef unsigned short sa_family_t;
struct sockaddr {
sa_family_t sa_family;
char sa_data[14];
};
struct in_addr {
unsigned long s_addr; // load with inet_pton()
};
struct sockaddr_in {
short sin_family; // e.g. AF_INET, AF_INET6
unsigned short sin_port; // e.g. htons(3490)
struct in_addr sin_addr; // see struct in_addr, above
char sin_zero[8]; // zero this if you want to
};
int main(void) {
int sfd;
const short family = AF_INET;
const char host[] = "127.0.0.1";
struct sockaddr addr;
struct sockaddr_in *addr_full = (struct sockaddr_in*)&addr;
if (sfd = socket(family, SOCK_STREAM, 0) < 0) return 1;
memset(&addr, 0, sizeof(struct sockaddr));
addr_full->sin_family = family;
addr_full->sin_port = htons(8000);
inet_pton(family, host, &(addr_full->sin_addr.s_addr));
if (connect(sfd, &addr, sizeof(struct sockaddr)) < 0) return 2;
close(sfd);
return 0;
}
沿线的某个地方我没有正确连接到我的 python -m SimpleHTTPServer
;报告 Serving HTTP on 0.0.0.0 port 8000
.
$ gcc my_program.c -o my_program
$ ./my_program
$ echo $?
2
我正在参加有关软件安全的 Coursera 课程;很多这个话题对我来说都是新的。
编辑:
删除重新定义并添加包括后:
#include <sys/socket.h>
#include <string.h>
#include <netinet/in.h>
int main(void) {
int sfd;
const short family = AF_INET;
const char host[] = "127.0.0.1";
struct sockaddr_in addr_full; // = (struct sockaddr_in*)&addr;
if (sfd = socket(family, SOCK_STREAM, 0) < 0) return 1;
memset(&addr_full, 0, sizeof(struct sockaddr));
addr_full.sin_family = family;
addr_full.sin_port = htons(8000);
inet_pton(family, host, &(addr_full.sin_addr.s_addr));
if (connect(sfd, (struct sockaddr*)&addr_full, sizeof(struct sockaddr)) < 0) return 2;
close(sfd);
return 0;
}
程序仍然以 2
退出。
您对包含文件的假设是错误的。包含文件只包含函数声明,不包含代码本身。他们不确定您的程序将如何链接到共享库。
包含文件只告诉编译器您在程序中调用的函数存在于某处,在某些外部库或您编写的另一个源文件中。编译后,链接器会尝试找到您的程序需要的所有函数,如果找不到,则链接失败。
尝试使用包含的必要文件(socket.h
等)编译您的代码。这会给你有用的警告,例如当你传递错误类型的参数时。
未正确分配套接字文件描述符。添加括号,我应该分配描述符,然后检查它的值:
if ((sfd = socket(family, SOCK_STREAM, 0)) < 0) return 1;
本子,
请获取 C
语言书籍并检查操作优先级。并经常这样做,即使是经验丰富的开发人员也会在这里犯错误。并且不要写这种疯狂的风格,请学习如何为人类写作:
if (sfd = socket(family, SOCK_STREAM, 0) < 0) return 1;
你应该这样做:
sfd = socket(family, SOCK_STREAM, 0);
if (sfd < 0)
{
/* perror() is pretty old style but some good check is recommended. */
perror("socket");
return 1;
}
剧透:<
在这里具有更高的优先级,因此 sfd
在您的代码中始终为 0。