user-0 提问: socket通信getpeername（）客户端ip获取总是错误

回复:
user: user-1
content: 找到错误了，getpeername第三个参数没有sizeod http://aigo.iteye.com/blog/1905564  #include<sys/types.h> #include<sys/socket.h> #include<netinet/in.h> #include<arpa/inet.h> #include<unistd.h> #include<string.h> #include<stdio.h> #include<errno.h> void printfd(int sock) { 	//thread  safe  C99 	socklen_t						peer_addr_size,selflen; 	struct sockaddr_in 			peer_addr,self; 	unsigned int				esme_port=0; 	char						esme_ip[200]; 	int ern; 	int ret=0; 	peer_addr_size=sizeof(struct sockaddr); 	ret=getpeername(sock,(struct sockaddr*)&peer_addr,&peer_addr_size); 	ern=errno; 	if(!ret){ 	printf("peer[%s]\n",inet_ntop(peer_addr.sin_family,&peer_addr.sin_addr,esme_ip,sizeof(esme_ip)));  	esme_port = ntohs(peer_addr.sin_port); 	printf("peer%d**[sock=%d] port[%d] ip[%s]\n",ret,sock,esme_port,esme_ip); 	}else 	{ 		printf("peer %s\n",strerror(ern)); 	} 	selflen=sizeof(struct sockaddr); 	ret=getsockname(sock, (struct sockaddr*)&self,&selflen); 	ern=errno; 	if(!ret){ 	printf("self[%s]\n",inet_ntop(self.sin_family,&self.sin_addr,esme_ip,sizeof(esme_ip))); 	esme_port = ntohs(self.sin_port); 	printf("self%d**[sock=%d] port[%d] ip[%s]\n",ret,sock,esme_port,esme_ip); 	}else 	{ 		printf("self %s\n",strerror(ern)); 	} }

user: user-1
content: void printfd(int sock) { 	//thread  safe  C99 	socklen_t						peer_addr_size,selflen; 	struct sockaddr_in 			peer_addr,self; 	unsigned int				esme_port=0; 	char						esme_ip[200];     	int ern; 	int ret=0; 	ret=getpeername(sock,(struct sockaddr*)&peer_addr,&peer_addr_size); 	ern=errno; 	if(!ret){ 		if(NULL!=inet_ntop(peer_addr.sin_family,&peer_addr.sin_addr,esme_ip,sizeof(esme_ip))){ 			//ip  线程   inet_ntoa不安全   			esme_port = ntohs(peer_addr.sin_port); 			printf("peer%d**[sock=%d] port[%d] ip[%s]\n",ret,sock,esme_port,esme_ip); 			}else{ 				ern=errno; 				printf("peer %s\n",strerror(ern)); 			} 	}else 	{ 		printf("peer %s\n",strerror(ern)); 	} 	 	ret=getsockname(sock, (struct sockaddr*)&self,&selflen); 	ern=errno; 	if(!ret){ 		if(NULL!=inet_ntop(self.sin_family,&self.sin_addr,esme_ip,sizeof(esme_ip))){ 			esme_port = ntohs(self.sin_port); 			printf("self%d**[sock=%d] port[%d] ip[%s]\n",ret,sock,esme_port,esme_ip); 	}else{ 				ern=errno; 				printf("peer %s\n",strerror(ern)); 			} 	}else 	{ 		printf("self %s\n",strerror(ern)); 	} }引用 4 楼 zhao4zhong1 的回复:/*	作用：tcp协议实现通信  */  #include<stdio.h> #include<stdlib.h> #include<sys/socket.h> #include<sys/types.h> #include<netinet/in.h> #include<string.h> #include <arpa/inet.h>  int main() { int sk=socket(AF_INET,SOCK_STREAM,0); struct sockaddr_in addr; addr.sin_family = AF_INET; addr.sin_addr.s_addr = INADDR_ANY; addr.sin_port = 10089;  bind(sk,(const struct sockaddr *)&addr,sizeof(addr)); listen(sk,30); char * buf = malloc(64); while(1) { struct sockaddr_in userip,servip,sq; socklen_t userlen; socklen_t servlen; char add[60]; char ipAddr[18]; int x = 0; int * lenth = malloc(4); char ZZaddr[200]; unsigned short ZZport; int sd=accept(sk,(struct sockaddr * __restrict__)&sq,lenth); strcpy(ZZaddr,inet_ntoa(sq.sin_addr)); ZZport=ntohs(sq.sin_port); printf("%s,  ,%d\n",ZZaddr,ZZport); getsockname(sd,(struct sockaddr * __restrict__)&servip,&servlen); strcpy(ZZaddr,inet_ntoa(servip.sin_addr)); ZZport=ntohs(servip.sin_port); printf("%s   %d\n",ZZaddr,ZZport);   getpeername(sd,(struct sockaddr * __restrict__)&userip,&userlen);// strcpy(ZZaddr,inet_pton(AF_INET,(const char * __restrict__)&userip.sin_addr,ipAddr)); ZZport=ntohs(userip.sin_port); printf("%d   %d\n",ZZaddr,ZZport); strcpy(ZZaddr,inet_ntop(AF_INET,&userip.sin_addr,ipAddr,sizeof(ipAddr))); ZZport=ntohs(userip.sin_port); printf("%s   %d\n",ZZaddr,ZZport);

user: user-1
content: 服务器accept后立即打印一下，getpeername 会错误Address family not supported by protocol。如果sleep(2)我得到的peer0**[sock=4] port[0] ip[0.0.0.0]，和客户端进行首发以后 答应正确peer0**[sock=4] port[49351] ip[127.0.0.1]   这种是什么原因？ 引用 4 楼 zhao4zhong1 的回复:/*	作用：tcp协议实现通信  */  #include<stdio.h> #include<stdlib.h> #include<sys/socket.h> #include<sys/types.h> #include<netinet/in.h> #include<string.h> #include <arpa/inet.h>  int main() { int sk=socket(AF_INET,SOCK_STREAM,0); struct sockaddr_in addr; addr.sin_family = AF_INET; addr.sin_addr.s_addr = INADDR_ANY; addr.sin_port = 10089;  bind(sk,(const struct sockaddr *)&addr,sizeof(addr)); listen(sk,30); char * buf = malloc(64); while(1) { struct sockaddr_in userip,servip,sq; socklen_t userlen; socklen_t servlen; char add[60]; char ipAddr[18]; int x = 0; int * lenth = malloc(4); char ZZaddr[200]; unsigned short ZZport; int sd=accept(sk,(struct sockaddr * __restrict__)&sq,lenth); strcpy(ZZaddr,inet_ntoa(sq.sin_addr)); ZZport=ntohs(sq.sin_port); printf("%s,  ,%d\n",ZZaddr,ZZport); getsockname(sd,(struct sockaddr * __restrict__)&servip,&servlen); strcpy(ZZaddr,inet_ntoa(servip.sin_addr)); ZZport=ntohs(servip.sin_port); printf("%s   %d\n",ZZaddr,ZZport);   getpeername(sd,(struct sockaddr * __restrict__)&userip,&userlen);// strcpy(ZZaddr,inet_pton(AF_INET,(const char * __restrict__)&userip.sin_addr,ipAddr)); ZZport=ntohs(userip.sin_port); printf("%d   %d\n",ZZaddr,ZZport); strcpy(ZZaddr,inet_ntop(AF_INET,&userip.sin_addr,ipAddr,sizeof(ipAddr))); ZZport=ntohs(userip.sin_port); printf("%s   %d\n",ZZaddr,ZZport);

user: user-2
content: /*	作用：tcp协议实现通信  */  #include<stdio.h> #include<stdlib.h> #include<sys/socket.h> #include<sys/types.h> #include<netinet/in.h> #include<string.h> #include <arpa/inet.h>  int main() { int sk=socket(AF_INET,SOCK_STREAM,0); struct sockaddr_in addr; addr.sin_family = AF_INET; addr.sin_addr.s_addr = INADDR_ANY; addr.sin_port = 10089;  bind(sk,(const struct sockaddr *)&addr,sizeof(addr)); listen(sk,30); char * buf = malloc(64); while(1) { struct sockaddr_in userip,servip,sq; socklen_t userlen; socklen_t servlen; char add[60]; char ipAddr[18]; int x = 0; int * lenth = malloc(4); char ZZaddr[200]; unsigned short ZZport; int sd=accept(sk,(struct sockaddr * __restrict__)&sq,lenth); strcpy(ZZaddr,inet_ntoa(sq.sin_addr)); ZZport=ntohs(sq.sin_port); printf("%s,  ,%d\n",ZZaddr,ZZport); getsockname(sd,(struct sockaddr * __restrict__)&servip,&servlen); strcpy(ZZaddr,inet_ntoa(servip.sin_addr)); ZZport=ntohs(servip.sin_port); printf("%s   %d\n",ZZaddr,ZZport);   getpeername(sd,(struct sockaddr * __restrict__)&userip,&userlen);// strcpy(ZZaddr,inet_pton(AF_INET,(const char * __restrict__)&userip.sin_addr,ipAddr)); ZZport=ntohs(userip.sin_port); printf("%d   %d\n",ZZaddr,ZZport); strcpy(ZZaddr,inet_ntop(AF_INET,&userip.sin_addr,ipAddr,sizeof(ipAddr))); ZZport=ntohs(userip.sin_port); printf("%s   %d\n",ZZaddr,ZZport);

user: user-2
content: inet_ntoa The Windows Sockets inet_ntoa function converts an (Ipv4) Internet network address into a string in Internet standard dotted format.  char FAR * inet_ntoa (   struct in_addr in   );   Parameters in  [in] A structure that represents an Internet host address.  Remarks The inet_ntoa function takes an Internet address structure specified by the in parameter and returns an ASCII string representing the address in ".'' (dot) notation as in "a.b.c.d''. The string returned by inet_ntoa resides in memory that is allocated by Windows Sockets. The application should not make any assumptions about the way in which the memory is allocated. The data is guaranteed to be valid until the next Windows Sockets function call within the same thread, but no longer. Therefore, the data should be copied before another Windows Sockets call is made.  Return Values If no error occurs, inet_ntoa returns a char pointer to a static buffer containing the text address in standard ".'' notation. Otherwise, it returns NULL.   QuickInfo   Windows NT: Yes   Windows: Yes   Windows CE: Use version 1.0 and later.   Header: Declared in winsock2.h.   Import Library: Link with ws2_32.lib.  See Also inet_addr

user: user-0
content: 大神求指点啊！！ 可以通信，但是ip输出不对，是不输出的时候不对还是getpeername函数用错了

user: user-0
content: 大神的意思是在Windows系统下么？我这是在linux系统上，难道函数用的 不对？