生成套接口地址
1.通用套接口地址
#include <sys/socket.h>
struct sockaddr {
sa_family_t sa_family;//地址族,Linux中为2字节
char sa_data[14];//地址数据
};
2.本地套机口地址
#include <sys/un.h>
struct sockaddr_un{
sa_family_t sun_family;//地址族,Linux中为2字节
char sun_path[108];//路径名
};
sun_family必须为 AF_LOCAL或者AF_UNIX它指定了结构必须根据sockaddr_un规则格式化。
sun_path 包含有效的UNIX路径名,结尾不需要空字符。
3.Internet(IPV4)套接口地址
#include <netinet/in.h>
struct sockaddr_in {
sa_faminly_t sin_family;//地址族
uint16_t sin_port;//端口号
struct in_addr sin_addr;//Internet 地址
unsigned char sin_zero[8];//占位字节
};
struct in_addr {
uint32_t s_addr;//Internet 地址
};
4. Internet(IPV6)套接口地址
struct socketaddr_in6 {
sa_family_t sin6_family;
uint16_t sin6_port;//端口号
uint32_t sin6_flowinfo;//流信息
struct in6_addr sin6_addr;//IPv6地址
};
struct in6_addr {
union {
uint8_t u6_addr8[16];
uint16_t u6_addr16[8];
uint32_t u6_addr32[4];
} in6_u;
};
//生成本地套接口例子
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <sys/un.h>
static void bail(const char* on_what)
{
perror(on_what);
exit(1);
}
int main(void)
{
int z;//返回的状态码
int sck_unix;//套接口
struct sockaddr_un adr_unix;//AF_UNIX
int len_unix;//长度
const char pth_unix[] = "/tmp/my_sock";//路径名
/* 建立AF_UNIX或者AF_LOCAL套接口 */
sck_unix = socket(AF_UNIX, SOCK_STREAM, 0);
if (sck_unix == -1)
bail("socket() error/n");
/* 为防止该套接口的路径名由于前次运行而保留下来,先进行删除操作,并忽视
* 错误
*/
unlink(pth_unix);
/* 生成AF_UNIX地址 */
memset(&adr_unix, 0, sizeof(adr_unix));
adr_unix.sun_family = AF_UNIX;
strncpy(adr_unix.sun_path,
pth_unix,
sizeof(adr_unix.sun_path)-1)
[sizeof(adr_unix.sun_path) - 1] = 0;
printf("sizeof(adr_unix.sun_path) -1 = %d/n", sizeof(adr_unix.sun_path) - 1);
len_unix = SUN_LEN(&adr_unix);//宏SUN_LEN调用strlen计算UNIX路径名的字符串长度,不包括空字节,注意一定要在
//adr_unix.sun_path[]添加一个'/0'
printf("len_unix is %d/n", len_unix);
/* 将套接口地址绑定到套接口 */
z = bind(sck_unix, (struct sockaddr *)&adr_unix, len_unix);
if (z == -1)
bail("bind () error/n");
/* 显示套接口*/
system("netstat -pa --unix 2>/dev/null |grep /'/tmp/my/' "
);
/* 关闭套接口并断开与其相应路径名的连接 */
close(sck_unix);
//unlink(pth_unix);
return 0;
}
//生成抽象的本地地址
//传统的AF_UNIX套接口存在缺陷:总有一个文件系统对象生成。不需要,不方便。
//我们只需要把路径的第一个字符设置为空
/*把第一字节设置为空*/
adr_unix.sun_path[0] = 0;
//生成Internet(IPv4)套接口地址
|-------------------|-----------------------|--------------------|---------------------|
| sin_family=AF_INET | sin_port | |
|-------------------|-----------------------|--------------------|---------------------|
| sin_addr |
|-------------------|-----------------------|--------------------|---------------------|
| sin_zero[8]
sin_port,sin_addr都必须是网络字节序的(大端)。
关于大端小端:
大小端表示多字节值的哪一端(小端或大端)存储在该值的起始地址。这由CPU的体系结构决定的。
对于0x1234
<---------地址增加方向
| 0x34 | 0x12 | 大端
| 0x12 | 0x34 | 小端(高高低低,就是 高字节存在高地址 低字节存在低地址)
//例子
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <string.h>
#include <sys/un.h>
#include <netinet/in.h>
#include <netinet/in.h>
#include <netinet/in.h>
static void bail(const char* on_what)
{
perror(on_what);
}
int main(void)
{
int z;//返回的状态码
int sck_inet;//套接口
struct sockaddr_in adr_inet;//AF_INET in.h里有定义
int len_inet;//地址长度***
const unsigned char IPno[] = {127,0,0,23};//本地回送地址
/* 生成一个IPv4 Internet 套接口 */
sck_inet = socket(AF_INET, SOCK_STREAM, 0);
if (sck_inet == -1)
bail("socket()");
/* 建立AF_INET 套接口地址 */
memset(&adr_inet, 0, sizeof(adr_inet));
adr_inet.sin_family = AF_INET;
adr_inet.sin_port = htons(9000);
memcpy(&adr_inet.sin_addr.s_addr, IPno, 4);
len_inet = sizeof(adr_inet);
/* 将地址绑定到套接口 */
z = bind(sck_inet,
(struct sockaddr*)&adr_inet,
len_inet);
if (z == -1)
bail("bind() error/n");
/* 显示所有已经绑定的套接口 */
system("netstat -pa --tcp 2>/dev/null"/* | sed -n /"1,/^Proto/p;/af_inet/p/""*/);
close(sck_inet);
return 0;
}
3. 生成套接口地址
最新推荐文章于 2021-05-15 12:00:53 发布