TCP/IP:连接服务器失败(错误原因:Connection refused)
TCP/IP:連接服務器失敗(錯誤原因:Connection refused)
Linux中,通過系統調用(system call) connect 連接指定服務器建立TCP連接。
connect 最常見的失敗原因是 Connection refused。
假設服務器IP是192.168.44.148,且并 未有 進程監聽端口是12500時:
若有TCP連接請求包到達192.168.44.148,則192.168.44.148的內核將 回復RST包 給客戶端。
此時,在客戶端一側看來就是connect連接失敗,被服務端拒絕連接。
Code:
客戶端:
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <errno.h> #include <string.h> #include <netdb.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h>int main() {int client_fd = socket(AF_INET, SOCK_STREAM, 0);if (client_fd < 0){fprintf(stderr, "create socket error=%d(%s)!!!\n", errno, strerror(errno));exit(1);}struct sockaddr_in server_addr;server_addr.sin_family = AF_INET;server_addr.sin_port = htons(12500);if (inet_pton(AF_INET, "192.168.44.148", &server_addr.sin_addr) <= 0){fprintf(stderr, "inet_pton error!!!\n");exit(1);}if (connect(client_fd, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0){fprintf(stderr, "socket connect error=%d(%s)!!!\n", errno, strerror(errno));exit(1);}fprintf(stdout, "connect to server ok!\n");close(client_fd); // free connectionreturn 0; }編譯:
[jiang@localhost client]$ gcc -o client client.c [jiang@localhost client]$ ll total 16 -rwxrwxr-x. 1 jiang jiang 8237 Jun 10 09:41 client -rw-rw-r--. 1 jiang jiang 906 Jun 10 09:29 client.c運行:
服務器主機:[test1280@localhost ~]$ ifconfig | grep "inet addr"inet addr:192.168.44.148 Bcast:192.168.44.255 Mask:255.255.255.0inet addr:127.0.0.1 Mask:255.0.0.0 [test1280@localhost ~]$ netstat -an | grep 12500客戶端主機:[jiang@localhost client]$ ./client socket connect error=111(Connection refused)!!!tcpdump抓取協議包:
[root@localhost ~]# tcpdump tcp port 12500 -i eth0 -s 0 -w jiang.cap tcpdump: listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes ^C2 packets captured 2 packets received by filter 0 packets dropped by kernelwireshark分析jiang.cap:
1)
客戶端調用 connect,發起TCP連接建立請求到服務端。
2)
服務器內核收到要連接本機12500端口的請求,發現并未有對應的監聽SOCKET,于是回復RST到客戶端。
3)
客戶端調用 connect 失敗,錯誤原因:Connection refused。
服務器Code:
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <errno.h> #include <string.h> #include <netdb.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h>#define BACKLOG 16int main() {// socketint listen_fd = socket(AF_INET, SOCK_STREAM, 0);if (listen_fd < 0){fprintf(stderr, "create socket error=%d(%s)!!!\n", errno, strerror(errno));exit(1);}int flag = 1;if (setsockopt(listen_fd, SOL_SOCKET, SO_REUSEADDR, &flag, sizeof(flag)) < 0){fprintf(stderr, "socket setsockopt error=%d(%s)!!!\n", errno, strerror(errno));exit(1);}// bindstruct sockaddr_in server_addr;server_addr.sin_family = AF_INET; // IPv4server_addr.sin_port = htons(12500); // Portserver_addr.sin_addr.s_addr = htonl(INADDR_ANY); // IPif (bind(listen_fd, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0){fprintf(stderr, "socket bind error=%d(%s)!!!\n", errno, strerror(errno));exit(1);}// listenif (listen(listen_fd, BACKLOG) < 0){fprintf(stderr, "socket listen error=%d(%s)!!!\n", errno, strerror(errno));exit(1);}fprintf(stdout, "server init ok, start to accept new connect...\n");// acceptint client_fd = accept(listen_fd, NULL, NULL);if (client_fd < 0){fprintf(stderr, "socket accept error=%d(%s)!!!\n", errno, strerror(errno));exit(1);}fprintf(stdout, "accept one new connect!!!\n");char msg[1024] = "";// read client-FIN=1 EOFwhile (read(client_fd, msg, sizeof(msg)-1) == 0)break;close(client_fd);return 0; }編譯:
[test1280@localhost server]$ gcc -o server server.c [test1280@localhost server]$ ll total 16 -rwxrwxr-x. 1 test1280 test1280 9616 Jun 10 09:51 server -rw-r--r--. 1 test1280 test1280 1555 Jun 10 09:50 server.c運行:
[test1280@localhost server]$ ./server server init ok, start to accept new connect... accept one new connect!!! [test1280@localhost ~]$ ifconfig | grep "inet addr"inet addr:192.168.44.148 Bcast:192.168.44.255 Mask:255.255.255.0inet addr:127.0.0.1 Mask:255.0.0.0 [test1280@localhost ~]$ netstat -an | grep 12500 tcp 0 0 0.0.0.0:12500 0.0.0.0:* LISTEN [jiang@localhost client]$ ./client connect to server ok!即使當前主機有進程監聽12500端口,connect依然有可能被拒絕連接
略微修改下服務器代碼(不使用地址通配INADDR_ANY):
// bindstruct sockaddr_in server_addr;server_addr.sin_family = AF_INET;server_addr.sin_port = htons(12500); // Port// if (inet_aton("0.0.0.0", &(server_addr.sin_addr)) != 1)// if (inet_aton("192.168.44.148", &(server_addr.sin_addr)) != 1)if (inet_aton("127.0.0.1", &(server_addr.sin_addr)) != 1){fprintf(stderr, "inet_aton error!!!\n");exit(1);}if (bind(listen_fd, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0){fprintf(stderr, "socket bind error=%d(%s)!!!\n", errno, strerror(errno));exit(1);}編譯 && 運行:
[test1280@localhost server]$ gcc -o server server.c [test1280@localhost server]$ ll total 16 -rwxrwxr-x. 1 test1280 test1280 9620 Jun 10 10:12 server -rw-r--r--. 1 test1280 test1280 1737 Jun 10 10:12 server.c [test1280@localhost server]$ ./server server init ok, start to accept new connect... [test1280@localhost ~]$ ifconfig | grep "inet addr"inet addr:192.168.44.148 Bcast:192.168.44.255 Mask:255.255.255.0inet addr:127.0.0.1 Mask:255.0.0.0 [test1280@localhost ~]$ netstat -an | grep 12500 tcp 0 0 127.0.0.1:12500 0.0.0.0:* LISTEN此時,在服務器上雖然有進程監聽12500端口,但是監聽套接字的IP地址是127.0.0.1(在127.0.0.1地址上監聽12500端口)。
如果我們在客戶端主機(192.168.44.144)上向【192.168.44.148:12500】發起TCP連接請求,將會被拒絕:
[jiang@localhost client]$ ifconfig | grep "inet addr"inet addr:192.168.44.144 Bcast:192.168.44.255 Mask:255.255.255.0inet addr:127.0.0.1 Mask:255.0.0.0 [jiang@localhost client]$ ./client socket connect error=111(Connection refused)!!!被拒絕原因是在148服務器上不存在監聽套接字【192.168.44.148:12500】,只有監聽套接字【127.0.0.1:12500】。
如果我們在服務端主機(192.168.44.148)上向【127.0.0.1:12500】發起TCP連接請求,將會被允許:
修改客戶端代碼:
struct sockaddr_in server_addr;server_addr.sin_family = AF_INET;server_addr.sin_port = htons(12500);if (inet_pton(AF_INET, "127.0.0.1", &server_addr.sin_addr) <= 0){fprintf(stderr, "inet_pton error!!!\n");exit(1);}編譯 && 運行:
[test1280@localhost client]$ ifconfig | grep "inet addr"inet addr:192.168.44.148 Bcast:192.168.44.255 Mask:255.255.255.0inet addr:127.0.0.1 Mask:255.0.0.0 [test1280@localhost client]$ gcc -o client client.c [test1280@localhost client]$ ./client connect to server ok!總結:
connect 發起TCP連接請求被拒絕是由于目標服務器上無對應的監聽套接字(IP && PORT)。
在哪個IP上監聽哪個端口,^_^。
總結
以上是生活随笔為你收集整理的TCP/IP:连接服务器失败(错误原因:Connection refused)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 《高速电路设计实践》- 读书笔记
- 下一篇: 计算机组装微课,计算机组装与维护微课教学