项目中通过http的法子调用了别样斯特林发动机的数量。后天同事反应,调用数据出现难题。出现难题时,现象如下:
[linuxidc.com@linuxidc logs]$curl
“”
[linuxidc.com@linuxidc logs]$curl: (7) couldn’t connect to host

摘要:socket bind的ip和port的选择

#import <arpa/inet.h>

  继续追踪,发现一而再的是叁个实体机ip,而非vip。
connect(3, {sa_family=AF_INET, sin_port=htons(2088),
sin_addr=inet_addr(“10.234.12.108”)}, 16) = -1 EINPROGRESS (Operation
now in progress)
poll([{fd=3, events=POLLOUT}], 1, 300000) = 1 ([{fd=3,
revents=POLLERR|POLLHUP}])
getsockopt(3, SOL_SOCKET, SO_ERROR, [8589934703], [4]) = 0
close(3) 

应用bind函数绑定ip和端口时有如下三种可能:

#import <netdb.h>

 
那让自家回忆了后面安装的vipserver。vipserver是Ali友爱开支的一个dns域名分析软件。查看了vipserver的日志,开掘它实在把域名分析到了重重实体机ip上。

ip地址端口结果

#include <sys/ioctl.h>

 
为何分析到实体机ip后就不能够正常调用服务了呢?和对方pe沟通后获悉,实体机监听的是2087端口,而vip监听的是2088端口。由此,在向实体机的2088端口发起连接伏乞时败北。

通配地址0内核选取ip地址和端口

@interfaceXCClient() {

 
别的还开掘一个难点,就是相同的时间安装vipserver的几台服务器,部分能健康剖判到vip,部分剖析到了实体机ip。初叶很疑心,后来意识是nscd搞的鬼。使用以下命令清除dns缓存后,全部的机器都深入分析到了实体机ip了。
sudo /usr/sbin/nscd -i hosts

通配地址非0内核选择ip地址,进度内定端口

intsock_fd;

 
由于vipserver深入分析的ip有标题,暂且关闭了vipserver。待对方pe完毕vipserver设置后,再启用。

本地ip地址0进度钦赐ip地址,内核采用端口

structhostent*host;

本文恒久更新链接地址:http://www.linuxidc.com/Linux/2016-07/133181.htm

本地ip地址非0进度钦命ip地址和端口

structsockaddr_inserver_addr;

威澳门尼斯人36366com 1

利用准绳:

intloopcount;

  1. 服务器进程一般在运行时都会bind有些端口(比如http的80端口),而客户端进度都不会钦点端口。若未调用bind接口,则内核会为其钦定二个一时端口。

}

服务端进度也可能有不点名端口的case,举个例子rpc服务。服务端进程在listen后向rpc服务注册进度注册本身的地址和端口。rpc客户端只必要向rpc服务登记进程诉求对应的劳动,就能够回到rpc服务的ip和port新闻。

staticintPortNum_Car;//端口号

2.
若钦赐ip地址,则该ip地址必须是属于其主机的互联网接口之一(127.0.0.1,网卡eth0地址192.168.0.102,别的网卡地址)。

constchar*IP_Car;//IP地址

对于tcp客户端来讲,其钦命发送ip数据报的源地址

设置端口号和服务器地址

对于tcp服务端来讲,其范围了该socket只收到指标地址为该ip的connect央浼。

PortNum_Car=16868;

若tcp服务端不点名ip,内核会把客户端发送的syn的指标地址作为服务端的源地址(该connect
socket的源地址)

NSString*ipString =@”192.168.43.1″;//那个ip地址要从服务端要

**注:三个listen socket能够accept多少个socket连接,accept再次来到的connect
socket的源地址恐怕为127.0.0.1,192.168.0.102,只怕别的本机ip **

IP_Car= ipString.UTF8String;

上面用代码证实下:

//上面创立并再而三端口

貌似,运营服务器监听的代码如下:

if((host=gethostbyname(IP_Car)) ==NULL) {

// 服务端代码intlistenfd, connfd;structsockaddr_in server_addr;   
listenfd = Socket(AF_INET, SOCK_STREAM,0);   
bzero(&server_addr,sizeof(server_addr));//
必须是互连网序server_addr.sin_family = AF_INET;   
server_addr.sin_addr.s_addr = htonl(INADDR_ANY);   
server_addr.sin_port = htons(1234);// 指定ip//    char *host =
“127.0.0.1”;//    inet_pton(AF_INET, host,
&server_addr.sin_addr);Bind(listenfd,
(SA*)&server_addr,sizeof(server_addr));    Listen(listenfd,
LISTENQ);while(1) {        len =sizeof(cli_addr);        connfd =
Accept(listenfd, (SA*)&cli_addr, &len);        printf(“connect from
%s, port:%d\n”,              inet_ntop(AF_INET,
&cli_addr.sin_威澳门尼斯人36366com,addr,buffer,sizeof(buffer)),             
ntohs(cli_addr.sin_port));structsockaddr_in peer_addr,
local_addr;// 获取connect fd 的本机ip和portinterr = getsockname(connfd,
(SA *)&local_addr, &len);if(err >=0) {            printf(“sock name
%s, port:%d\n”,                  inet_ntop(AF_INET,
&local_addr.sin_addr,buffer,sizeof(buffer)),
ntohs(local_addr.sin_port));        }// 获取客户端的本机ip和porterr =
getpeername(connfd, (SA*) &peer_addr, &len);if(err >=0) {         
  printf(“peer sock name %s, port:%d\n”,                 
inet_ntop(AF_INET, &peer_addr.sin_addr,buffer,sizeof(buffer)),
ntohs(peer_addr.sin_port));        }    }

NSLog(@”host Error”);

服务端程序绑定在通配ip

}

开发银行绑定在通配ip和1234端口的服务端程序

if((sock_fd=socket(AF_INET,SOCK_STREAM,0)) == -1) {

运用telnet 127.0.0.1 1234发令连接服务端

NSLog(@”create Socket Error”);

服务端显示

}

connect from 127.0.0.1, port:58271

//设置调用closesocket()后,仍可承继起用该socket。调用closesocket()一般不会即时关闭socket,而经验TIME_WAIT的过程

sock name 127.0.0.1, port:1234

BOOLnREUSEADDR =true;

peer sock name 127.0.0.1, port:58271

setsockopt(sock_fd,SOL_SOCKET,SO_REUSEADDR,
(constchar*)&nREUSEADDR,sizeof(int));

行使telnet 192.168.0.102 1234老是服务端

server_addr.sin_family=AF_INET;

服务端展现

server_addr.sin_port=htons(PortNum_Car);

connect from 192.168.0.102, port:58282

server_addr.sin_addr= *((structin_addr*)host->h_addr);

Author

发表评论

电子邮件地址不会被公开。 必填项已用*标注