#include #include
int socket(int domain, int type, int protocol);
#define AF_UNSPEC PF_UNSPEC
#define AF_LOCAL PF_LOCAL
#define AF_UNIX PF_UNIX
#define AF_FILE PF_FILE
#define AF_INET PF_INET
#define AF_AX25 PF_AX25
#define AF_IPX PF_IPX
#define AF_APPLETALK PF_APPLETALK
#define AF_NETROM PF_NETROM
#define AF_BRIDGE PF_BRIDGE
#define AF_ATMPVC PF_ATMPVC
#define AF_X25 PF_X25
#define AF_INET6 PF_INET6
#define AF_ROSE PF_ROSE
#define AF_DECnet PF_DECnet
#define AF_NETBEUI PF_NETBEUI
#define AF_SECURITY PF_SECURITY
#define AF_KEY PF_KEY
#define AF_NETLINK PF_NETLINK
#define AF_ROUTE PF_ROUTE
#define AF_PACKET PF_PACKET
#define AF_ASH PF_ASH
#define AF_ECONET PF_ECONET
#define AF_ATMSVC PF_ATMSVC
#define AF_RDS PF_RDS
#define AF_SNA PF_SNA
#define AF_IRDA PF_IRDA
#define AF_PPPOX PF_PPPOX
#define AF_WANPIPE PF_WANPIPE
#define AF_LLC PF_LLC
#define AF_IB PF_IB
#define AF_MPLS PF_MPLS
#define AF_CAN PF_CAN
#define AF_TIPC PF_TIPC
#define AF_BLUETOOTH PF_BLUETOOTH
#define AF_IUCV PF_IUCV
#define AF_RXRPC PF_RXRPC
#define AF_ISDN PF_ISDN
#define AF_PHONET PF_PHONET
#define AF_IEEE802154 PF_IEEE802154
#define AF_CAIF PF_CAIF
#define AF_ALG PF_ALG
#define AF_NFC PF_NFC
#define AF_VSOCK PF_VSOCK
#define AF_KCM PF_KCM
#define AF_QIPCRTR PF_QIPCRTR
#define AF_SMC PF_SMC
#define AF_MAX PF_MAX
type 可选字段:
error 字段:
int sockfd = socket ( AF_INET , SOCK_STREAM , 0 );
int sockfd = socket ( AF_INET , SOCK_DGRAM , 0 );
int sockfd = socket ( PF_UNIX , SOCK_STREAM , 0 );
/* 描述通用套接字地址的结构 */
struct sockaddr
{
__SOCKADDR_COMMON (sa_); /* 常用数据:地址族和长度. */
char sa_data[14]; /* 地址数据. */
};
socket 中所有的函数都是使用上面的结构来表示一个地址(可以任意协议族的地址)
IPV4 的地址信息结构体为:
struct sockaddr_in {
__kernel_sa_family_t sin_family; /*指定的协议族,AF_INTE*/
__be16 sin_port; /* 端口号(网络字节序)*/
struct in_addr sin_addr; /*IP 地址*/
/*填充到结构 sockaddr 的大小,保证所有协议的地址结构体都可以使用 socket 表示. */
unsigned char __pad[__SOCK_SIZE__ - sizeof(short int) -
sizeof(unsigned short int) - sizeof(struct in_addr)];
};
其中:
struct in_addr {
__be32 s_addr; //IP 地址,in_addr_t 类型,32 位无符号整型
};
使用上面结构体需要的头文件为:
#include #include// 为了使用 IPV4 地址结构体
本地通信的地址信息结构体为:
struct sockaddr_un {
__kernel_sa_family_t sun_family; /* 协议族,AF_UNIX */
char sun_path[UNIX_PATH_MAX]; /* 路径名,因为本地通信就是进程间通信,没有 IP 地址一言,所以需要一个计算机中的目录路径,就像 ftok 通过路径名获取 key 一样 */
};
使用上面结构体需要的头文件为:
#include #include// 为了使用 IPV4 地址结构体
#include
#include
#include
int inet_aton(const char *cp, struct in_addr *inp);
struct sockaddr_in saddr ;inet_aton ( "192.168.41.243" , & saddr . sin_addr );
#include
#include
#include
in_addr_t inet_addr(const char *cp);
struct sockaddr_in Saddr; //保存服务器的地址信息的结构体
memset(&Saddr,0,sizeof(struct sockaddr_in)); //清空结构体
Saddr.sin_family = AF_INET; //协议族,AF_INET 表示使用 IPV4 的协议族
Saddr.sin_port = htons(atoi(argv[2])); //端口号,但是要求的是网络字节序
Saddr.sin_addr.s_addr = inet_addr(argv[1]); //32bit 的一个 IP 地址
#include
#include
#include
in_addr_t inet_network(const char *cp);
#include
int inet_pton(int af, const char *src, void *dst);
#include
#include
#include
printf ( "[ %s ] \n " , inet_ntoa ( addr . sin_addr ));
#include
const char *inet_ntop(int af, const void *src, char *dst, socklen_t size);
#include
#include
#include
struct in_addr inet_makeaddr(int net,int host)
unsigned long net,host;
net = 0x0000007F;
host = 0x00000001;
struct in_addr ip = inet_makeaddr(net,host);
#include
#include
#include
in_addr_t inet_lnaof(struct in_addr in)
const char * addr = "127.0.0.1" ;unsigned long ip = inet_network ( addr );unsigned long host_id = inet_lnaof ( ip );
#include
#include
#include
in_addr_t inet_netof(struct in_addr in)
const char * addr = "127.0.0.1" ;unsigned long ip = inet_network ( addr );unsigned long network_id = inet_netof ( ip );
在 linux 中提供了下面四个函数用于网络字节序和主机字节序之间的转换。
#include
uint32_t htonl(uint32_t hostlong);
#include
uint16_t htons(uint16_t hostlong);
address . sin_port = htons ( atoi (port)); // 将端口号 port 转换为网络字节序
#include
uint32_t ntohl(uint32_t netlong);
#include
uint16_t ntohs(uint16_t netlong);
printf ( " 客户端 IP: %s , 客户端 Port: %d \n " , inet_ntoa ( caddr . sin_addr ), ntohs ( caddr . sin_port ));
#include
#include
int bind(int sockfd, const struct sockaddr *addr,socklen_t addrlen);
【函数功能】
//2.绑定一个通信 IP 地址(作为服务器本身的 IP)
struct sockaddr_in saddr; //保存服务器的地址(IP+port)
memset(&saddr,0,sizeof(struct sockaddr_in)); //清空结构体
saddr.sin_family = AF_INET;
inet_aton(argv[1], &saddr.sin_addr);
saddr.sin_port = htons(atoi(argv[2]));
int ret = bind(sockfd,(struct sockaddr *)&saddr,sizeof(saddr));
if(ret == -1)
{
perror("bind error");
exit(-1);
}
#include
#include
int listen(int sockfd, int backlog);
listen ( sockfd , 250 );
#include
#include
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
struct sockaddr_in caddr ; // 保存客户端的地址 (IP+port)socklen_t len = sizeof ( caddr );int confd = accept (sockfd,( struct sockaddr * ) & caddr , & len );
#include
#include
int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
struct sockaddr_in Saddr; //保存服务器的地址信息的结构体
memset(&Saddr,0,sizeof(struct sockaddr_in)); //清空结构体
Saddr.sin_family = AF_INET; //协议族,AF_INET 表示使用 IPV4 的协议族
Saddr.sin_port = htons(atoi(3456));//端口号,但是要求的是网络字节序
Saddr.sin_addr.s_addr = inet_addr("192.168.41.234");
int r = connect(sock,(struct sockaddr *)&Saddr,sizeof(Saddr));
if(r == -1) //连接失败
{
perror("connect error");
return -1;
}
ssize_t write ( int fd, const void * buf, size_t count);
char buf[1024] = {0};
memset(buf,0,sizeof(buf));
scanf("%[^\n]",buf);
printf("%ld\n",strlen(buf));
int ret = write(sock,buf,strlen(buf));
if(ret <= 0)
{
perror("sendto error");
return -1;
}
#include
ssize_t writev(int fd, const struct iovec *iov, int iovcnt);
struct iovec{void * iov_base ; // 内容的地址__kernel_size_t iov_len ; // 偏移量};
struct iovec iv [ 2 ];iv [ 0 ].iov_base = header_buf;iv [ 0 ].iov_len = strlen ( header_buf );iv [ 1 ].iov_base = file_buf;iv [ 1 ].iov_len = file_stat.st_size;ret = writev (confd, iv , 2 );
#include
#include
ssize_t send(int sockfd, const void *buf, size_t len, int flags);
ret = send ( sockfd , "nishiliangzaiya" , 15 , 0 );
#include
#include
ssize_t sendto(int sockfd, const void *buf, size_t len,int flags,const struct sockaddr *dest_addr, socklen_t addrlen);
ret = sendto (sockfd, "nishiliangzaima" , 15 , 0 , NULL , 0 );if (ret == - 1 ){perror ( "sendto error" );}
char buf [ 1024 ] = { 0 };fgets ( buf , 1024 , stdin );int ret = sendto ( sockfd , buf , strlen ( buf ), 0 ,( struct sockaddr * ) & addr , sizeof ( addr ));
#include
#include
ssize_t sendmsg(int sockfd, const struct msghdr *msg, int flags);
struct msghdr
{
void *msg_name; /* 发送/接收方的协议地址 */
socklen_t msg_namelen; /* 地址数据长度 */
struct iovec *msg_iov; /* 要发送/接收的数据向量*/
size_t msg_iovlen; /*向量中的元素数。*/
void *msg_control; /*辅助数据(例如 BSD 文件传递)*/
size_t msg_controllen; /*辅助数据缓冲区长度。*/
int msg_flags; /* 接收到的消息上的标志。忽略 */
};
ssize_t read ( int fd, void * buf, size_t count);
char buf [ 1024 ];memset ( buf , 0 , sizeof ( buf ));int ret = read ( client , buf , sizeof ( buf ));
#include
ssize_t readv(int fd, const struct iovec *iov, int iovcnt);
struct iovec{void * iov_base ; // 内容的地址__kernel_size_t iov_len ; // 偏移量};
#include
#include
ssize_t recv(int sockfd, void *buf, size_t len, int flags);
#include
#include
ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,struct sockaddr *src_addr, socklen_t *addrlen);
// 读取服务器的回复消息 -UDP 读取memset (buf, 0 , 1024 );struct sockaddr_in src_addr ; // 保存消息发送方的地址 (IP+port)memset ( & src_addr, 0 , sizeof ( struct sockaddr_in)); // 清空结构体socklen_t src_len = sizeof ( src_addr ); // 保存可用大小recvfrom (sockfd,buf, 1024 , 0 ,( struct sockaddr * ) & src_addr , & src_len );
#include
#include
ssize_t recvmsg(int sockfd, struct msghdr *msg, int flags);
struct msghdr{void * msg_name ; /* 发送 / 接收方的协议地址 */socklen_t msg_namelen ; /* 地址数据长度 */struct iovec * msg_iov ; /* 要发送 / 接收的数据向量 */size_t msg_iovlen ; /* 向量中的元素数。 */void * msg_control ; /* 辅助数据 ( 例如 BSD 文件传递 )*/size_t msg_controllen ; /* 辅助数据缓冲区长度。 */int msg_flags ; /* 接收到的消息上的标志。忽略 */};
[flags]: 发送标志,一般为 0,也可以是几个宏的组合值
#include
int shutdown(int sockfd, int how);