linux网络编程----套接字编程

来源:互联网 发布:如何找到淘宝套现商家 编辑:程序博客网 时间:2024/06/03 19:20

源代码在github上点击这里

TCP/IP协议规定,网络数据流应采用大端字节序,即低地址高字节

套接字:IP地址 + TCP端口号
(socket) 一个套接字,唯一标识网络通讯中的一个进程
TCP/IP协议中,两个进程若想建立连接,就离不开套接字,它是TCP连接中的端点

套接字地址结构:(用来保存套接字的相应信息)

linux下

IPv4套接字地址结构

IPv4套接字地址结构通常也叫做“网际套接字地址结构”,以sockaddr_in命名:定义在<netinet/in.h>   struct in_addr     {          in_addr_t s_addr;  /*32位IP地址*/     };     struct sockaddr_in     {          short sin_family;                 /*Address family一般来说AF_INET(地址                                              族)PF_INET(协议族)*/          unsigned short sin_port;          /*Port number(必须要采用网络数据格式,普                                            通数字可以用htons()函数转换成网络数据格式的数字)*/          struct in_addr sin_addr;          /*IP address in network byte                                           order(Internet address)*/          unsigned char sin_zero[8];        /*Same size as struct sockaddr没有实                                              际意义,只是为了 跟SOCKADDR结构在内存中                                              对齐,是为了让sockaddr与sockaddr_in                                              两个数据结构保持大小相同而保留的空字节。*/     };

通用套接字地址结构:不建立该类型的结构体变量,而只是在传参的时候,进行强制类型转换成该类型,
和void*类型一样,为了函数支持各种类型的数据

struct sockaddr               {     unsigned  short  sa_family;        /* address family, AF_xxx */     char  sa_data[14];                 /* 14 bytes of protocol address */};     AF_前缀代表地址族,PF_前缀代表协议族     sa_family是地址家族,一般都是“AF_xxx”的形式。好像通常大多用的是都是AF_INET。     sa_data是14字节协议地址。     此数据结构用做bind、connect、recvfrom、sendto等函数的参数,指明地址信息。     但一般编程中并不直接针对此数据结构操作,而是使用另一个与sockaddr等价的数据结构,如sockaddr_in,sockaddr_un,sockaddr_in6...

套接字地址结构体使用方式 :

IPv4地址用sockaddr_in结构体表示,IPv6地址用sockaddr_in6结构体表示,UNIX Domain
Socket地址用sockaddr_un结构体表示,为了让socket API可以接受各种类型的sockaddr结构体
指针做参数,例如bind,accept,connect等函数,这些函数的参数应该设置为void* 类型的指
针,但socket API的实现早于ANSI C标准化,那个时候还没有void* 类型,因此这些函数的参数
都用struct sockaddr* 类型表示,所以struct sockaddr*是一个通用类型指针。在传递参数之前
要强制类型转换:如
struct sockaddr_in servaddr;
bind(sock_fd,(struct sockaddr *)&servaddr,sizeof(servaddr));

建立TCP连接所用函数解析:

1.socket();      函数原型:  int socket(int domain,int type,int protocol);      作用 :socket函数是一种可用于根据指定的地址族、数据类型和协议来分配一个套接口的描述      字及其所用的资源的函数      参数:           domain:  一个地址描述。目前仅支持AF_xxxx格式:AF_INET代表IPv4地址           type:       新套接字的类型描述:SOCK_STREAM  : 提供面向连接的稳定数据传           输,即TCP协议。 SOCK_dGRAM:表示面向数据报的传输协议,即UDP协议           protocol :    套接字所用的协议。如调用者不想指定,可用0指定,表示缺省。      返回值:          成功返回文件描述符>0,失败返回<0,
2.bind()     函数原型:int bind(int sockfd, const struct sockaddr *addr,  socklen_t addrlen);     作用: 绑定服务器ip地址和端口,因为服务器程序所监听的网络地址和端口号通常是固定不变     的,将参数sockfd和addr绑定在一起,使sockfd这个用于网络通讯的文件描述符监听addr所描     述的地址和端口号     参数:               sockfd:socket创建成功的返回值               addr :存有套接字信息的结构体的地址(注意强制类型转换)               addrlen: 前一个套接字结构体类型的变量的长度:addr参数可以接受多种协议的               sockaddr结构体,而它们的长度各不相同,所以需要第三个addrlen指定结构体的长度。     返回值:                    成功返回0,失败返回-1
3.  listen():         函数原型:int listen(int sockfd,int backlog);         作用:仅被TCP服务器调用,声明sockfd处于监听状态,并且最多有backlog个客户端处于         连接等待状态,         返回值:成功返回0,失败返回-1
4.accept():           函数原型:int accept(int sockfd,struct sockaddr *addr,socklen_t *addrlen)           作用:用于接收客户端的连接请求           参数:                    sockfd:称为监听套接字,即服务器的套接字,也是其文件描述符                    addr : 客户端的套接字地址结构体的变量的地址                    addrlen:传入传出型参数,传入的是调用者提供的缓冲区的长度,以避免缓                    冲区溢出,传出的是客户端地址结构体的实际长度(有可能没有占满调用者提                    供的缓冲区)           返回值:                 成功返回客户端的IP地址和端口号(即套接字),失败返回-1
5.网络字节序和主机字节序的转换:(为使网络程序具有可移植性,使同样的代码在大端小端机器都可编译正常运行,对应于开篇的首句话)       #include <arpa/inet.h>       uint32_t htonl(uint32_t hostlong);       uint16_t htons(uint16_t hostshort);       uint32_t ntohl(uint32_t netlong);       uint16_t ntohs(uint16_t netshort);     h表示host,n表示network,l表示32位长整数(IP地址),s表示16为短整数(端口号);     例如:htonl表示将32位的长整数从主机字节序转换为网络字节序,即:将IP地址转换后准备发     送,若主机是小端字节序,这些函数将参数做相应的大小端转换后返回,若是大端字节序,这些函     数不做转换,将参数原封不动的返回
6.字符串转in_addr的函数:        int inet_aton(const char *strptr, struct in_addr *addrptr);        in_addr_t inet_addr(const char *strptr);        int inet_pton(int family,const char* strptr,void *addrptr);
7.in_addr转字符串的函数:       char *inet_ntoa(struct in_addr inaddr);       const char *inet_ntop(int family,const void* addrptr,char* strptr,size_t len);      其中inet_pton和inet_ntop不仅可以转换IPv4的in_addr,还可以转换IPv6的in6_addr,因      此函数接口是void *addrptr
8. connect():     函数原型:int connect (int sockfd,const struct sockaddr *addr,socklen_t addrlen)     作用:客户端调用connect连接服务器     参数:其参数形式和bind一致,区别在于bind的参数是自己的地址,而connect参数是对方的地址。     返回值:          成功返回0,失败返回-1.
0 0
原创粉丝点击