您的位置:首页 > 运维架构 > Linux

学习笔记《实战Linux Socket编程》第二章

2007-12-21 21:15 197 查看
内容介绍:
一、通用套接口地址
#include <sys/socket.h>
struct sockaddr
{
sa_family_t sa_family;//地址族(无符号的短整数在linux中是两个字节)
char sa_data[14]; //地址数据
}
通用套接口地址本身没什么用处,但它为其他地址结构提供了一个重要的参考模型

二、sockaddr_un地址结构
#include <sys/un.h>
struct sockaddr_un
{
sa_family_t sun_family; //地址族
char sun_path[108]; //路径名
}
当使用lpr(1)找印文件时,系统实际是在使用本地套接口与找印服务进行通讯,本地套接口也被称为AF_UNIX域,sockaddr_un地址结构对应的就是AF_LOCAL和AF_UNIX地址结构

三、IPv4套接口地址
#include <netinet.h>
struct socket_in
{
sa_family_t sin_family; //地址族
uint16_t sin_port; //端口号
struct in_addr sin_addr;//Internet地址
unsigned sin_zero[8]; //占位字节
}
in_addr包含一个32位无符号整数,sin_zero[8]是不被使用的。
注 : sin_port sin_addr 都是网络字节序。
什么是网络字节序:
1.小端字节序:是一种将低序字节存储在起始位置的方法(如Intel的CPU)
2.大端字节序:是一种将高序字节存储在起始位置的方法
而网络上的数据的标准是大端字节序,如果Linux系统是在大端字节序的机器上运行,不需要转换字节,只要提供一个简单的宏替换,否则在用下面的函数进行转换:
#include <netinet/in.h>
unsigned long htonl(unsigned long hostlong);
unsigned short htons(unsigned short hostshort);
unsigned long ntohl(unsigned long netlong);
unsigned short ntohs(unsigned short netshort);
这里的短整数是16位,长整数为32位

四、X.25地址
#include <linux/x25.h>
struct sockaddr_x25
{
sa_family_t sx25_addr[16];//必须是AF_X25
x25_address sx25_addr; //X.121地址
}
typedef struct
{
char x25_addr[16];
}x25_address;
有关信息可参考 x25(4)手册,一个X.25的网络地址(由X.121标准定义)由一串十进制数组成,在sockaddr_x25结构中,主机号不能以空字符结尾

五、AF_INET6
struct sockaddr_in6
{
sa_family_t sin6_family;
uint6_t sin6_port;
uint6_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;
};

六、AF_AX25(业余无线电AX.25地址)
struct full_sockaddr_ax25
{
struct sockaddr_ax25 fsa_ax25;
ax25_address fsa_digipeater[AX25_MAX_DIGIS];
};
struct sockaddr_ax25
{
sa_family_t sax25_family;
ax25_address sax25_call;
int sax25_ndigis;
};
typedef struct
{
/*6 call+SSID(移位ASCII)*/
char ax25_call[7];
}ax25_address;
#define sax25_uid sax25_ndigis;

实例:
/////////////////////第一个实例////////////////////
//gcc p29
//AF_UNIX套接口示例
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
#include <errno.h>
#include <sys/un.h>//////////
#include <sys/stat.h>////////

//本函数用于报告错误并返回shell
static void bail(const char *on_what)
{
perror(on_what);
exit(1);
}

int main(int argc, char *argv[])
{
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()");
}

//为了防止该套接口的路径名由于前次运行程序时而保留下来,
//这里先进行删除.忽视错误或无错误
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);
adr_unix[sizeof(adr_unix.sun_path) - 1] = 0;

len_unix = SUN_LEN(&adr_unix);

//将地址绑定至套接口
z = bind(sck_unix, (struct sockaddr *) &adr_unix, len_unix);

if (z == -1)
{
bail("bind()");
}

//显示所有已绑定的套接口
system("netstat -pa --unix 2 | sed -n '/^Active UNIX/,/^Proto/p;/a.out/p'");

//关闭套接口并断开一其相应路径名的连接
close(sck_unix);
unlink(pth_unix);

return 0;
}

/////////////////////第二个实例////////////////////

//gcc p32.c

//AF_UNIX套接口示例
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/un.h>
#include <sys/stat.h>
#include <unistd.h>

//本函数用于报错并返回shell
static void bail(const char *on_what)
{
perror(on_what);
exit(1);
}

int main(int argc, char *argv[])
{
int z; //返回的状态码
int sck_unix; //套接口
struct sockaddr_un adr_unix;//AF_UNIX
int len_unix; //长度
const char pth_unix[] = "Z*MY-SOCKET*";//抽象地址

//建立AF_UNIX(AF_LOCAL)套接口
sck_unix = socket(AF_UNIX, SOCK_STREAM, 0);

if (sck_unix == -1)
bail("socket()");

//生成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;

len_unix = SUN_LEN(&adr_unix);

//将路径名的第一个字节置为空
adr_unix.sun_path[0] = 0;

//将地址绑定到套接口
z = bind(sck_unix, (struct sockaddr *)&adr_unix, len_unix);

if (z == -1)
bail("bind()");

//显示所有已绑定的套接口;
system("netstat -pa --unix | sed -n '/^Active UNIX/,/^Proto/p;/a.out/p'");

//关闭套接口并断开与其相应路径名的连接
close(sck_unix);
return 0;
}

/////////////////////第三个实例////////////////////

//gcc p39.c

//建立一个特定的AF_INET套接口地址
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
#include <string.h>
#include <netinet/in.h>/*定义struct sockaddr_in*/
//#include <sys/stat.h>//???

//本函数用于报错并返回到shell
static void bail(const char *on_what)
{
perror(on_what);
exit(1);
}

int main(int argc, char *argv[])
{
int z; //返回的状态码
int sck_inet; //套接口
struct sockaddr_in adr_inet; //AF_INET
int len_inet; //长度
const unsigned char IPno[] = {127,0,0,1};//本地回送地址

//生成一个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()");

//显示所有已绑定的套接口
system("netstat -pa --tcp | sed -n '1,/^Proto/p;/a.out/p'");
//这里看不到结果???????

close(sck_inet);
return 0;
}

/////////////////////第四个实例////////////////////

//gcc p41.c

//X.25套接口地址示例
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <linux/x25.h>

//报错函数
static void bail(const char *on_what)
{
perror(on_what);
exit(1);
}

int main(int argc, char *argv[])
{
int z; //返回的状态码
int sck_x25; //套接口
struct sockaddr_x25 adr_x25; //AF_X25
int len_x25; //长度
const char x25_host[] = "79400900";//X.121地址

//生成一个AF_X25套接口
sck_x25 = socket(AF_X25, SOCK_SEQPACKET, 0);

if (sck_x25 == -1)
bail("socket()");

//建立AF_X25套接口地址
adr_x25.sx25_family = AF_X25;
strcpy(adr_x25.sx25_addr.x25_addr, x25_host);
len_x25 = sizeof(adr_x25);

//将地址绑定到套接口
z = bind(sck_x25, (struct sockaddr *)&adr_x25, len_x25);

if (z == -1)
bail("bind()");

puts("X.25 SOCKETS");
system("cat /proc/net/x25/socket");
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: