当我在终端中输入命令./client www.google.com 80
时,我得到一个错误:
connect() failed: Connection refused
这段代码的目的是获取客户端和服务器之间的RTT,其中包含我输入到终端中的任何URL。
下面是我的代码:#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <netdb.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <sys/time.h>
#define RCVBUFSIZE 32
void DieWithError(char *errorMessage);
int getAddressInfo(const char* host, unsigned short* port, struct sockaddr_in* sock_addr);
int main(int argc, char *argv[]) {
int sock;
struct sockaddr_in httpServAddr;
unsigned short httpServPort;
char *httpRequest = "GET/ HTTP/1.1rn"
"Host: %srn"
"Connection: closernrn";
char httpBuffer[RCVBUFSIZE];
int bytesRcvd, totalBytesRcvd;
if (argc < 2 || argc > 3) {
fprintf(stderr, "Usage: %s <Server IP/URL> [<HTTP Port>]n", argv[0]);
exit(1);
}
const char* host = argv[1];
if (getAddressInfo(host, &httpServPort, &httpServAddr) != 0) {
DieWithError("Failed to get server address information");
}
if (argc == 3) {
httpServPort = atoi(argv[2]);
} else {
httpServPort = 80;
}
if ((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
DieWithError("socket() failed");
}
memset(&httpServAddr, 0, sizeof(httpServAddr));
httpServAddr.sin_family = AF_INET;
httpServAddr.sin_port = htons(httpServPort);
if (connect(sock, (struct sockaddr *) &httpServAddr, sizeof(httpServAddr)) < 0) {
DieWithError("connect() failed");
}
char request[strlen(httpRequest) + strlen(host) + 1];
sprintf(request, httpRequest, host);
if (send(sock, request, strlen(request), 0) != strlen(request)) {
DieWithError("send() sent a different number of bytes than expected");
}
totalBytesRcvd = 0;
printf("Received: ");
struct timeval start, end;
gettimeofday(&start, NULL);
while ((bytesRcvd = recv(sock, httpBuffer, RCVBUFSIZE - 1, 0)) > 0) {
totalBytesRcvd += bytesRcvd;
httpBuffer[bytesRcvd] = ' ';
printf("%s", httpBuffer);
}
gettimeofday(&end, NULL);
long rtt = (end.tv_sec - start.tv_sec) * 1000 + (end.tv_usec - start.tv_usec) / 1000;
if (bytesRcvd < 0) {
DieWithError("recv() failed");
}
printf("nnRound-trip time: %ld msn", rtt);
close(sock);
exit(0);
}
int getAddressInfo(const char* host, unsigned short* port, struct sockaddr_in* httpServAddr) {
struct addrinfo hints = {0};
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
struct addrinfo* result;
int ret = getaddrinfo(host, NULL, &hints, &result);
if (ret != 0) {
fprintf(stderr, "getaddrinfo() failed: %sn", gai_strerror(ret));
return -1;
}
// Copy the server address information to the httpServAddr struct
memcpy(httpServAddr, (struct sockaddr_in*)result->ai_addr, sizeof(struct sockaddr_in));
*port = ntohs(httpServAddr->sin_port);
freeaddrinfo(result);
return 0;
}
void DieWithError(char *errorMessage) {
perror(errorMessage);
exit(1);
}
我应该注意什么,或者考虑改变我的代码吗?我完全是初学者。
我期望以毫秒为单位获得RTT。我试过在终端中输入不同的url,并更改端口号。我不确定问题是我的代码还是我的设置。我根本没有编辑我的代码的配置,所以也许这就是问题所在。
做了这些…
if (getAddressInfo(host, &httpServPort, &httpServAddr) != 0) { DieWithError("Failed to get server address information"); }
…随后执行this只会适得其反:
memset(&httpServAddr, 0, sizeof(httpServAddr));
。您刚刚删除了您检索到的地址信息。
和最好是无用的,尽管它也可能适得其反:
httpServAddr.sin_family = AF_INET;
您只需要设置端口。保留通过getAddrInfo()
获得的所有其他内容,其中将包括正确的地址族。
您在填充httpServAddr
后将其归零。
先将其归零,然后填充。
const char* host = argv[1];
memset(&httpServAddr, 0, sizeof(httpServAddr));
if (getAddressInfo(host, &httpServPort, &httpServAddr) != 0) {
DieWithError("Failed to get server address information");
}
if (argc == 3) {
httpServPort = atoi(argv[2]);
} else {
httpServPort = 80;
}
httpServAddr.sin_port = htons(httpServPort);
if ((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
DieWithError("socket() failed");
}