一 点睛
一个套接字绑定了地址,就可以通过函数获取它的套接字的地址了。套接字通信需要本地和远程两端建立套接字,这样获取地址可以分别获取本地套接地址和获取远程套接字地址。
其中,获取本地套接字地址的函数是getsockname,这个函数在下面两种情况下可以获得本地套接字地址。
-
本地套接字通过bind函数绑定了地址。
-
本地套接字没有绑定地址,但通过connect函数和远程建立了连接,此时内核会分配一个地址给本地套接字。
二 实战——绑定后获取本地套接字地址
1 代码
#include <stdlib.h>
#include <sys/types.h>
#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>
#include "unistd.h"
#include "errno.h"
#include <arpa/inet.h> //for inet_ntoa
int main()
{
int sfp, nfp;
struct sockaddr_in s_add, c_add;
socklen_t sin_size;
unsigned short portnum = 10051;
struct sockaddr_in serv;
socklen_t serv_len = sizeof(serv);
sfp = socket(AF_INET, SOCK_STREAM, 0);
if (-1 == sfp)
{
printf("socket fail ! \r\n");
return -1;
}
printf("socket ok !\r\n");
printf("ip=%s,port=%d\r\n", inet_ntoa(serv.sin_addr), ntohs(serv.sin_port));
int on = 1;
setsockopt(sfp, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));//允许地址的立即重用
bzero(&s_add, sizeof(struct sockaddr_in));
s_add.sin_family = AF_INET;
s_add.sin_addr.s_addr = inet_addr("192.168.0.110");
s_add.sin_port = htons(portnum);
if (-1 == bind(sfp, (struct sockaddr *)(&s_add), sizeof(struct sockaddr)))
{
printf("bind fail:%d!\r\n", errno);
return -1;
}
printf("bind ok !\r\n");
getsockname(sfp, (struct sockaddr *)&serv, &serv_len);
printf("ip=%s,port=%d\r\n", inet_ntoa(serv.sin_addr), ntohs(serv.sin_port));
return 0;
}
2 运行
[root@localhost test]# g++ -o test test.cpp
[root@localhost test]# ./test
socket ok !
ip=0.0.0.0,port=0
bind ok !
ip=192.168.0.110,port=10051