这是一些C代码,我必须简单地测试互联网连接。任何关于效率和重构本程序的评论/建议将不胜感激。
int testConnection(void)
{
int status;
struct addrinfo host_info;
struct addrinfo *host_info_list;
memset(&host_info, 0, sizeof host_info);
#ifdef DEBUG
fprintf(stdout,"Setting up the structs...");
#endif
host_info.ai_family = AF_UNSPEC; // IP version not specified. Can be both.
host_info.ai_socktype = SOCK_STREAM; // Use SOCK_STREAM for TCP or SOCK_DGRAM for UDP.
status = getaddrinfo("www.google.com", "80", &host_info, &host_info_list);
if (status != 0) fprintf(stdout, "Address info error:: %s\n", gai_strerror(status));
#ifdef DEBUG
fprintf(stdout, "Creating a socket...\n");
#endif
int socketfd ;
socketfd = socket(host_info_list->ai_family, host_info_list->ai_socktype, host_info_list->ai_protocol);
if (socketfd == -1) fprintf(stderr, "Socket error\n");
#ifdef DEBUG
fprintf(stdout, "Connecting...");
#endif
status = connect(socketfd, host_info_list->ai_addr, host_info_list->ai_addrlen);
if (status < 0) fprintf(stderr, "Error while connecting.\n");
#ifdef DEBUG
fprintf(stdout, "Sending message...\n");
#endif
const char *msg = "GET / HTTP/1.1\nhost: www.google.com\n\n";
int len = strlen(msg);
ssize_t bytes_sent = send(socketfd, msg, len, 0);
if (bytes_sent == 0) fprintf(stderr, "No bytes sent.\n");
#ifdef DEBUG
fprintf(stdout, "Bytes sent: %d\n", bytes_sent);
fprintf(stdout, "Waiting to recieve data...\n");
#endif
char incomming_data_buffer[1000];
ssize_t bytes_recieved = recv(socketfd, incomming_data_buffer,1000, 0);
// If no data arrives, the program will just wait here until some data arrives.
if (bytes_recieved == 0) fprintf(stderr, "Host shut down.\n");
if (bytes_recieved == -1) fprintf(stderr, "Recieve error.\n");
incomming_data_buffer[bytes_recieved - 2] = '\0';
#ifdef DEBUG
fprintf(stdout, "Bytes recieved: %d\n", bytes_recieved);
fprintf(stdout, "%s\n", incomming_data_buffer);
fprintf(stdout, "Receiving complete. Closing socket...\n");
#endif
freeaddrinfo(host_info_list);
close(socketfd);
#ifdef DEBUG
fprintf(stdout, "Socket closed.\n");
#endif
return 0;
}发布于 2013-08-15 20:16:26
一些评论,大多是次要的评论:
我将提取到一个函数的服务器连接:
static int connect_server(const struct addrinfo *host_info)
{
struct addrinfo *host_info_list;
int fd = -1;
int status = getaddrinfo(...);
while(...) {
fd = socket(...);
status = connect(...);
}
freeaddrinfo(host_info_list);
return fd;
}所有那些调试的东西都让人分心。也许这是暂时的,但如果你想把它留在里面,我建议提取它:
#include <stdarg.h>
static inline void debug(const char *format, ...)
{
#ifdef DEBUG
va_list ap;
va_start(ap, format);
vfprintf(stdout, format, ap);
va_end(ap);
#endif
}并称之为:
debug("Bytes recieved: %ld\n%s\nReceiving complete. Closing socket...\n",
bytes_recieved,
incomming_data_buffer);如果调试未定义,内联debug函数将为空,并将在编译期间被排除-它将消失。
显然你需要循环才能读到整个信息..。读完后,你会扔掉最后两个字节。
buffer[bytes_recieved - 2] = '\0';recv调用填充了缓冲区,因此要正确终止\0,需要指定一个较小的缓冲区:
char buffer[1000];
ssize_t bytes_recieved = recv(socketfd, buffer, sizeof buffer - 1, 0);
...
if (bytes_recieved > 0) {
buffer[bytes_recieved] = '\0';
}注意sizeof的使用而不是显式的1000
还有其他的事情..。
getaddrinfo的手册页建议循环遍历返回的地址列表,而不是仅仅使用第一个地址(以防第一个地址不起作用)。strlen,而是使用sizeof:const char msg[] = "GET / HTTP/1.1\nhost: www.google.com\n\n";ssize_t bytes_sent = send(socketfd,msg,sizeof of msg - 1,0);注意msg[],而不是*msgperror或strerror等。https://codereview.stackexchange.com/questions/29805
复制相似问题