Linux编程常用的函数(八) 网络编程

 (八)网络编程


  1、socket函数:为了执行网络输入输出,一个进程必须做的第一件事就是调用socket函数获得一个文件描述符。
#include<socket.h>
int socket(int family, int type, int protocol);//成功返回非负描述字;失败返回-1
  第一个参数指明了协议簇,目前支持5种协议簇,最常用的有AF_INET(IPv4协议)和AF_INET6(IPv6协议);第二个参数指明 套接口类型,有三种类型可选:SOCK_STrEAM(字节流套接口)、SOCK_DGrAM(数据报套接口)和SOCK_rAW(原始套接口);如果套 接口类型不是原始套接口,那么第三个参数就为0。

  2、connect函数:当用socket建立了套接口后,可以调用connect为这个套接字指明远程端的地址;如果是字节流套接口,connect就使用三次握手建立一个连接;如果是数据报套接口,connect仅指明远程端地址,而不向它发送任何数据。
int connect(int sockfd, const struct sockaddr *servaddr, socklen_t addrlen);
//成功返回0;失败返回-1
  第一个参数是socket函数返回的套接口描述字;第二和第三个参数分别是一个指向套接口地址结构的指针和该结构的大小。
  这些地址结构的名字均已“sockaddr_”开头,并以对应每个协议族的唯一后缀结束。以IPv4套接口地址结构为例,它以“sockaddr_in”命名,定义在头文件<netinet/in.h>;以下是结构体的内容:
struct in_addr {
in_addr_t s_addr; //IPV4地址
};
struct sockaddr_in {
uint8_t sin_len;//无符号的8位整数
sa_family_t sin_family;//套接口地址结构地址族,这里为AF_INET
in_port_t sin_port;//TCP或UDP端口
struct in_addr sin_addr;//地址
char sin_zero[8];
};

  3、bind函数:为套接口分配一个本地IP和协议端口,对于网际协议,协议地址是32位IPv4地址或128位IPv6地址与16位的 TCP或UDP端口号的组合;如指定端口为0,调用bind时内核将选择一个临时端口,如果指定一个通配IP地址,则要等到建立连接后内核才选择一个本地 IP地址。
int bind(int sockfd, const struct sockaddr *myaddr, socklen_t addrlen);//成功0失败-1
  第一个参数是socket函数返回的套接口描述字;第二和第第三个参数分别是一个指向特定于协议的地址结构的指针和该地址结构的长度。

  4、listen函数:listen函数仅被TCP服务器调用,它的作用是将用sock创建的主动套接口转换成被动套接口,并等待来自客户端的连接请求。
int listen(int sockfd, int backlog);//成功返回0;失败-1
第一个参数是socket函数返回的套接口描述字;第二个参数规定了内核为此套接口排队的最大连接个数。由于listen函数第二个参数的原 因,内核要维护两个队列:以完成连接队列和未完成连接队列。未完成队列中存放的是TCP连接的三路握手为完成的连接,accept函数是从以连接队列中取 连接返回给进程;当以连接队列为空时,进程将进入睡眠状态。
  5、accept函数:accept函数由TCP服务器调用,从已完成连接队列头返回一个已完成连接,如果完成连接队列为空,则进程进入睡眠状态。
int accept(int sockfd,struct sockaddr * cliaddr,socklen_t * addrlen);  
// 返回:非负描述字---成功   -1---失败
  第一个参数是socket函数返回的套接口描述字;第二个和第三个参数分别是一个指向连接方的套接口地址结构和该地址结构的长度;该函数返回的是一个全新的套接口描述字;如果对客户段的信息不感兴趣,可以将第二和第三个参数置为空。

  6、inet_pton函数:将点分十进制串转换成网络字节序二进制值,此函数对IPv4地址和IPv6地址都能处理。
int inet_pton(int family,const char * strptr,void * addrptr);
//返回:1---成功 0---输入不是有效的表达格式 -1---失败
  第一个参数可以是AF_INET或AF_INET6:第二个参数是一个指向点分十进制串的指针:第三个参数是一个指向转换后的网络字节序的二进制值的指针。

  7、inet_ntop函数:和inet_pton函数正好相反,inet_ntop函数是将网络字节序二进制值转换成点分十进制串。
const char * inet_ntop(int family,const void *addrptr,char * strptr,size_t len);
//返回:指向结果的指针---成功   NULL---失败
  第一个参数可以是AF_INET或AF_INET6:第二个参数是一个指向网络字节序的二进制值的指针;第三个参数是一个指向转换后的点分十进制串的指针;第四个参数是目标的大小,以免函数溢出其调用者的缓冲区。
     8. int send(int sockfd, const void *msg, int len, int flags);
  Sockfd是你想用来传输数据的socket描述符,msg是一个指向要发送数据的指针。
  Len是以字节为单位的数据的长度。flags一般情况下置为0(关于该参数的用法可参照man手册)。
  char *msg = "Beej was here!"; int len, bytes_sent; ... ...
  len = strlen(msg); bytes_sent = send(sockfd, msg,len,0); ... ...
  send()函数返回实际上发送出的字节数,可能会少于你希望发送的数据。所以需要对send()的返回值进行测量。当send()返回值与len不匹配时,应该对这种情况进行处理。

  9.int recv(int sockfd,void *buf,int len,unsigned int flags);
  Sockfd是接受数据的socket描述符;buf 是存放接收数据的缓冲区;len是缓冲的长度。Flags也被置为0。Recv()返回实际上接收的字节数,或当出现错误时,返回-1并置相应的errno值。
  10. int sendto(int sockfd, const void *msg,int len,unsigned int flags,const struct sockaddr *to, int tolen);
  该函数比send()函数多了两个参数,to表示目地机的IP地址和端口号信息,而tolen常常被赋值为sizeof (struct sockaddr)。Sendto 函数也返回实际发送的数据字节长度或在出现发送错误时返回-1。
  11. int recvfrom(int sockfd,void *buf,int len,unsigned int flags,struct sockaddr *from,int *fromlen);
   from是一个struct sockaddr类型的变量,该变量保存源机的IP地址及端口号。fromlen常置为sizeof(struct sockaddr)。当recvfrom()返回时,fromlen包含实际存入from中的数据字节数。Recvfrom()函数返回接收到的字节数或 当出现错误时返回-1,并置相应的errno。
  应注意的一点是,当你对于数据报socket调用了connect()函数时,你也可以利用send()和recv()进行数据传输,但该socket仍然是数据报socket,并且利用传输层的UDP服务。但在发送或接收数据报时,内核会自动为之加上目地和源地址信息。
  12. struct hostent *gethostbyname(const char *name); //实现域名和IP的转换
  函数返回一种名为hosten的结构类型,它的定义如下:
  struct hostent {
     char *h_name; /* 主机的官方域名 */
     char **h_aliases; /* 一个以NULL结尾的主机别名数组 */
     int h_addrtype; /* 返回的地址类型,在Internet环境下为AF-INET */
     int h_length; /*地址的字节长度 */
     char **h_addr_list; /* 一个以0结尾的数组,包含该主机的所有地址*/
     };

13. int getsockopt(int sockfd,int level,int optname,void *optval,socklen_t *optlen)
int setsockopt(int sockfd,int level,int optname,const void *optval,socklen_t *optlen)

level指定控制套接字的层次.可以取三种值: 1)SOL_SOCKET:通用套接字选项. 2)IPPROTO_IP:IP选项. 3)IPPROTO_TCP:TCP选项.
optname指定控制的方式(选项的名称),我们下面详细解释

optval获得或者是设置套接字选项.根据选项名称的数据类型进行转换


选项名称 说明 数据类型
========================================================================
SOL_SOCKET
------------------------------------------------------------------------
SO_BROADCAST 允许发送广播数据 int
SO_DEBUG 允许调试 int
SO_DONTROUTE 不查找路由 int
SO_ERROR 获得套接字错误 int
SO_KEEPALIVE 保持连接 int
SO_LINGER 延迟关闭连接 struct linger
SO_OOBINLINE 带外数据放入正常数据流 int
SO_RCVBUF 接收缓冲区大小 int
SO_SNDBUF 发送缓冲区大小 int
SO_RCVLOWAT 接收缓冲区下限 int
SO_SNDLOWAT 发送缓冲区下限 int
SO_RCVTIMEO 接收超时 struct timeval
SO_SNDTIMEO 发送超时 struct timeval
SO_REUSERADDR 允许重用本地地址和端口 int
SO_TYPE 获得套接字类型 int
SO_BSDCOMPAT 与BSD系统兼容 int
======================================================================
IPPROTO_IP
--------------------------------------------------------------------------
IP_HDRINCL 在数据包中包含IP首部 int
IP_OPTINOS IP首部选项 int
IP_TOS 服务类型
IP_TTL 生存时间 int
======================================================================
IPPRO_TCP
--------------------------------------------------------------------------
TCP_MAXSEG TCP最大数据段的大小 int
TCP_NODELAY 不使用Nagle算法 int
======================================================================
关于这些选项的详细情况请查看 Linux Programmer''s Manual
14. TCP客户端的过程
  socket()->[*对所要连接的server对应的sockaddr_in结构中的sin_family,sin_addr.s_addr,sin_port赋值*]->connect()-> { write()->read()-> } close()
    TCP服务端的过程
  socket()->[*对server所对应的sockaddr_in机构中的sin_family,sin_addr.s_addr,sin_port进行赋值*]->bind()->listen()->{ accept()-> read()->write()-> }close()

15.UDP客户的过程
  [*对所要连接的server对应的sockaddr_in结构中的sin_family,sin_addr.s_addr,
sin_port赋值*]->socket()->{ sendto()->recvfrom()-> } close()
UDP服务端的过程
  socket()->[对server对应的sockaddr_in结构中的sin_family,sin_addr.s_addr,
sin_port赋值] –>bind()->{ recvfrom()->sendto()-> }close()

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值