socket编程流程

字节序转换(hton)

#include <netinet/in.h>
unsigned long int htonl(unsigned long int hostlong);
unsigned short int htons(unsigned short int hostshort);
unsigned long int ntohl(unsigned long int netlong);
unsigned short int ntohs(unsigned short int netshort);

通用地址

#include <bits/socket.h>
struct sockaddr
{
	sa_family_t sa_family; //存放协议族
    char sa_data[14];	   //存放地址
};

专用地址

//本地协议族
#include <sys/un.h>
struct sockaddr_un
{
	sa_famliy_t sin_famliy;	//协议族
    char sun_path[108];		//路径
};

//IPv4协议族
struct sockaddr_in
{
    sa_famliy_t sin_famliy;	//协议族
    u_int16_t sin_port;		//端口号
    struct in_addr sin_addr;//地址结构体
};
struct in_addr { u_int32_t s_addr; };

IP地址转换(aton)

#include <arpa/inet.h>
in_addr_t inet_addr(const char* strptr);	//字符串转IPv4地址
int inet_aton(const char* cp, struct in_addr* inp );//字符串转IPv4地址
char* inet_ntoa(struct in_addr in );//IPv4地址转字符串,不可重入

a可以理解成ASCII码,n可以理解成net,便于记忆。

创建socket

#include <sys/types.h>
#include <sys/socket.h>
int socket (int domain, int type, int protocal );

绑定socket和地址

#include <sys/types.h>
#include <sys/socket.h>
int bind (int sockfd, const struct sockaddr* my_addr, socklen_t addlen );
//前边的专用地址的指针强制转换成 struct sockaddr* 就行

监听socket

#include <sys/socket.h>
int listen( int sockfd, int backlog ); //backlog是指完全连接(ESTABLISHED)的客户端的上限

接受连接

#include <sys/types.h>
#include <sys/socket.h>
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen ); //成功返回客户端的文件描述符

发起连接(客户端)

#include <sys/types.h>
#include <sys/socket.h>
int connect(int server_fd, const struct sockaddr *serv_addr, socklen_t addrlen ); //成功返回0

关闭连接

#include <unistd.h>
int close(int fd); //通用文件描述符关闭,将fd的引用计数减一

#include <sys/socket.h>
int shutdown(int sockfd, int howto ); //网络专用,howto取值SHUT_RD, SHUT_WR, SHUT_RDWR。

TCP数据读写

#include <sys/types.h>
#include <sys/socket.h>
ssize_t recv(int sockfd, void *buf, size_t len, int flags );
ssize_t send(int sockfd, void *buf, size_t len, int flags );

UDP读写

#include <sys/types.h>
#include <sys/socket.h>
ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addlen);
ssize_t sendto(int sockfd, void *buf, size_t len, int flags, struct sockaddr *dest_addr, socklen_t *addlen);

通用读写

#include <sys/socket.h>
ssize_t recvmsg(int sockfd, struct msghdr *msg, int flags );
ssize_t sendmsg(int sockfd, struct msghdr *msg, int flags );
struct msghdr
{
    void *msg_name;			//socket地址
    socklen_t msg_namelen	//socket地址长度
    struct iovec *msg_iov;	//分散的内存块数组
    int msg_iovlen;			//内存块数量
    void *msg_control;		//指向辅助数据的起始位置
    socklen_t msg_controllen;//辅助数据长度
    int msg_flags;			//复制函数中的flags
};
struct iovec
{
  	void *iov_base;	//内存起始地址
    size_t iov_len;	//这块内存长度
};

msg_name对于TCP连接而言没有意义,必须设置NULL。

posted @ 2022-07-02 10:16  hellozhangjz  阅读(164)  评论(0)    收藏  举报