套接字不仅支持本地无关的两个进程之间的双向通信,而且支持跨网络的,运行在不同机器的进程间的通信。
可以通过int socket(int domain,int type,int protocol)建立套接字,通过int close(int socket)关闭(销毁)套接字,通过int shutdown(int socket,int how)断开套接字的连接。
建立套接字
#include <sys/socket.h>
int socket(int domain,int type,int protocol);
domian:通信域。
AF_UNIX:UNIX通信域,同一台计算机的任意两个进程,通过文件系统进行通信,文件系统的路径作为套接字的地址。
AF_INET:网络通信域,IPV4网路传输协议。
AF_INET6:网络通信域,IPV6网络传输协议。
type:套接字类型。
SOCK_STREAM:字节流套接字。
SOCK_DGRAM:数据流套接字。
protocol:具体的某个协议(一般置为0,使用系统默认的)
返回值为套接字描述字。
关闭套接字(销毁)
#include <unistd.h>
int close(int scoket);
scoket:套接字描述字。
断开套接字的连接
#include <sys/scoket.h>
int shutdown(int scoket,int how);
scoket:套接字描述字。
how:以那种方式断开链接
SHUT_RD:停止从此套接字接收数据。
SHUT_WR:停止从次套接字传送数据。
SHUT_RDWR:停止从此套接字接收和发送数据。
套接字的地址结构
/*IPV4*/
struct in_addr
{
in_addr_t s_addr;
};
/*IPV6*/
struct in6_addr
{
uint8 s6_addr[16];
};
字符串IP地址格式和二进制IP地址格式的互相转换
#include <arpa/inet.h>
int inet_aton(const char *name,struct in_addr *addr);
char * inet_ntoa(struct in_addr inaddr);
int inet_pton(int family,const char *nameptr,struct in_addr *addrptr);
consr char * inet_ntop(int family,void *addrptr,char *nameptr,size_t len);
hostent表示主机网络地址数据库记录的数据结构其中至少包含:
struct hostent
{
char *h_name; //主机名称
char **h_aliases; //主机别名
int h_addrtype; //主机地址类型
int h_length; //地址长度
char **h_addr_list; //指向主机网络地址的指针。
};
获取主机的信息:
#include <netdb.h>
struct hostent *gethostbyname(const char *name); /*获取主机信息*/
struct hostent *gethostbyaddr(const char *addr,size_t length,int type);/*获取主机信息*/
#include <netdb.h>
void sethostent(int stapopen); /*建立和域名服务器的链接*/
struct hostent *gethostent(); /*获取一条主机数据库的下一条记录*/
void endhostent(); /*关闭主机地址数据库*/
在网络通信中套接字地址由机器IP地址和端口号组成,IP时网络中一台计算机的唯一标识,端口号是区分同一台计算机不同的服务进程。
#include <netdb.h>
/*
*****************************************
描述服务信息库信息的数据结构
*****************************************
*/
struct servent
{
char *s_name; //服务程序的正式名称
char *s_aliases; //服务程序的别名
int s_port; //服务程序对应的端口号
char *s_proto; // 和服务程序一起使用的协议名称
};
获取和查询端口号
#include <netdb.h>
struct servent *getservbyname(const char *name,const char *proto);
struct servent *getservbyport(int port,const char *proto);
/*扫描服务数据库*/
void setservent(int stayopen); /*打开数据库准备扫描*/
struct servent *getservent(void);/*获取数据库下一条信息*/
void endservent(void) /*关闭数据库*/
套接字地址数据结构
(1)UNIX通信域
<span style="font-size:14px;">struct scokaddr_un
{
sa_family_t sun_family; //指明地址族
char sun_path[]; //文件路径
}</span>
(2)IPV4
struct scokaddr_in
{
sa_family_t sin_family; //指明地址族
in_port_t sin_port; //16位端口号
struct in_addr sin_addr; //32位IPV4
unsigned char sin_zero[8]; //保留
};
(3)IPV6
struct scokaddr_in6
{
sa_family_t sin6_family; //指明地址族
in_port_t sin6_port; //16位端口号
uint32_t sin6_addr; //IPV6流标识和优先级信息
struct in6_addr sin6_addr; //128位IPV6
};
(4)通用套接字地址结构
<span style="font-size:14px;">struct sockassr
{
sa_family_t sa_family;
char sa_data[];
};</span>
通过scoket在系统中创建无名的套接字,其他进程无法访问,通过bind可以给套接字指定名字(路径或地址,通常是只有对外提供服务的套接字),使其能够被访问。
<span style="font-size:14px;">#include <sys/scoket.h>
int bind(int scoket,const struct scokaddr,socklen_t address_len);</span>
socket:套接字描述字。
sockaddr:地址
address_len:结构体的长度
成功返回0,失败返回-1并置errno