我正在开发一个简单的C ++程序,并且想使用C套接字。是否可以通过在外部“ C”中声明而不是包含
我们可以使用extern“ C”声明libc绑定,例如write:
extern "C" {
int write(int fd, const char *buf, int count);
};
但是,当声明所需的套接字函数时,结果将不可靠。我发现我可以创建套接字和设置选项,但是connect()总是超时。
这里是使用纯外部“ C”声明的示例
gcc extern.cpp -o extern ; ./extern
extern "C" {
struct hostent {
char * h_name;
char ** h_aliases;
int h_addrtype;
int h_length;
char ** h_addr_list;
};
#define h_addr h_addr_list[0]
struct in_addr {
unsigned long s_addr;
};
struct sockaddr {
unsigned short sa_family;
char sa_data[14];
};
struct sockaddr_in {
short sin_family;
unsigned short sin_port;
struct in_addr sin_addr;
char sin_zero[8];
};
void* memset(void*, int, long unsigned int);
void* memcpy(void*, const void*, long unsigned int);
int write(int, const char*, int);
int close(int);
hostent* gethostbyname(const char*);
int socket(int, int, int);
int connect(int, sockaddr*, int);
int send(int, const char*, int, int);
int recv(int, char*, int, int);
int getsockopt(int, int, int, void*, unsigned int*);
int setsockopt(int, int, int, const void*, unsigned int);
unsigned short htons(unsigned short);
void perror(const char*);
void exit(int);
#define AF_INET 2
#define SOCK_STREAM 1
#define TCP_NODELAY 1
#define TCP_SYNCNT 7
#define IPPROTO_TCP 6
};
void error(const char *s) {
perror(s);
exit(1);
}
int main() {
hostent *hp;
int nodelay = 1;
int sockfd;
struct sockaddr_in serv_addr;
if ((sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
error("socket");
}
setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, (const char *)&nodelay, sizeof(int));
memset(&serv_addr, '0', sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(80);
if((hp = gethostbyname("stackoverflow.com")) == 0) {
error("gethostbyname");
}
memcpy(&serv_addr.sin_addr, hp->h_addr, hp->h_length);
// Reduce sock timeout
int synRetries = 2;
setsockopt(sockfd, IPPROTO_TCP, TCP_SYNCNT, &synRetries, sizeof(synRetries));
// When using extern "C" this seems to timeout
if (connect(sockfd, (sockaddr*)(&serv_addr), sizeof(struct sockaddr_in)) < 0) {
close(sockfd);
error("connect");
}
send(sockfd, "GET / HTTP/1.1\r\n\r\n\0", 19, 0);
char buf[1024];
recv(sockfd, buf, 1024, 0);
write(0, buf, 1024);
close(sockfd);
return 0;
}
我希望connect()函数能够解决;但是,除非我加入<sys/socket.h>
,否则connect()会超时。
有没有解决的办法,我感兴趣的是看看是否有可能使用纯外部“ C”来使用套接字。
答案 0 :(得分:0)
您似乎已经从gethostbyname获得了一个IPv6地址,并将其写入sockaddr,从而使缓冲区溢出并破坏了内容。然后,您尝试将IPv6地址的开头部分作为IPv4地址连接,而该IP不想与您对话。
这行还是很疯狂的,但我看不出为什么它会失败:
memset(&serv_addr,'0',sizeof(serv_addr))
应该是
memset(&serv_addr,0,sizeof(serv_addr))