UNIX网络编程总结四

socket:

  为了执行网络I/O,一个进程作的第一件事就是调用socket函数。缓存

  family指明协议族,type指明类型,除非在原始套接口,protocol通常为0,并不是全部的family,type组合都是有效的。服务器

  socket函数在成功时返回一个小的非负整数值,称为套接口描述字。网络

 

connect:

  客户在调用函数connect前没必要非得调用bind,必要时,内核会选择ip地址和临时端口。并发

  TCP套接口,connect会激活三路握手,成功或者出错时返回。socket

  几种错误:函数

  一、TCP客户未收到SYN分节响应,返回ETIMEDOUT。接口

  二、服务器无服务等待连接,返回ECONNREFUSED。队列

  三、客户发出的SYN分节在中间路由器引起目的不可达ICMP错误,返回EHOSTENREACH或ENETUNREACH错误。进程

 

bind:

  给套接口分配一个本地协议地址。ip

  对于TCP,bind能够指定端口号,能够指定ip地址,能够都指定,也能够都不指定。

  若让内核为套接口选择一个临时端口,函数bind不返回所选的值,必须调用getsockname来返回协议地址。

 

listen:

  当函数socket建立一个套接口时,他被假设为主动套接口,listen将未使用的套接口变为被动套接口,告诉内核,此套接口能够接受链接请求。

  内核要维护两个队列,两队列之和不超过backlog:

  一、未完成链接队列,已有客户发出并到达服务端,服务端等待完成三路握手,SYN_RCVD。

  二、已完成链接队列,已完成三路握手,ESTABLISHED。

  Berkeley为backlog增长模糊因子,1.5,即最大可支持值*1.5。

  不要把backlog定义为0,由于不一样实现有不一样的解释。

  当一个客户SYN到达时,若队列是满的,则TCP忽略该分节,可是不发RST,客户会重发该分节。

  套接字接收缓存区存储握手完成但未accept时到达的数据。

 

accept:

  由TCP服务器调用,用于从已完成链接队列队头返回下一个已完成链接,已完成链接为空,进程进入睡眠。

  accept的第三个参数addrlen是值-结果参数,传入套接口地址结构长度,返回内核存放在该套接字地址结构内的确切字节数。

  accept会返回一个内核生成的全新的描述符,表明所返回客户的TCP链接,accept第一个参数称为监听套接字描述符,返回的为已链接套接字描述符,一个服务器通常只有一个监听套接字描述符,但有不少已链接套接字描述符,它随客户链接建立,随服务结束关闭。

 

fork和exec:

  # include <unisted.h>

  pid_t fork(void);

  fork调用一次返回两次,父进程返回子进程的ID号,子进程返回0。

  父进程fork前打开的描述符在fork返回后由子进程共享。

  fork典型用法:

  一、建立自身进程的副本。

  二、一个进程执行另外一个程序,先建立自身副本,而后副本调用exec将自身替换为新程序。

  exec:

  # include <unistd.h>

  int execl(const char *pathname, const char *arg0, ... /* (char *) 0 */);

int execv(const char *pathname, char *const *argv[]);

int execle(const char *pathname, const char *arg0, ... /* (char *) 0 , char *const envp[] */);

int execve(const char *pathname, char *const *argv[], char *const envp[]);

int execlp(const char *filename, const char *arg0, ... /* (char *) 0 */);

int execvp(const char *filename, char *const *argv[]);

进程调用exec前打开的描述符一般跨exec继续保持打开,但可使用fcntl设置FD_CLOEXEC描述符标志禁止掉。

 

并发服务器:

  链接创建,accept返回,服务器调用fork,而后由子进程服务客户,父进程关闭已链接套接字,由于每一个文件或套接字都有引用计数器子进程会将其加1,父进程关闭不会致使计数器为0,因此父进程关闭子进程不会终止客户链接。父进程关闭已链接套接字后,就能够继续等待下一次链接了。

 

close:

  close一个TCP套接字的默认行为是把该套接字标记为已关闭,而后当即返回调用进程,该套接字描述符不能再由调用进程使用,但TCP仍然会尝试发送已排队等待发送到对端的任何数据,发送完毕后发正常TCP终止序列。

 

getsockname和getpeername

  getsockname返回某个套接字关联的本地地址;

  # include <sys/socket.h>

  int getsocketname(int sockfd, struct sockaddr *localaddr, socklen_t *addrlen);

  一、在未调用bind的TCP客户上,connect成功返回,getsockname返回内核赋予该连接的本地IP地址和本地端口号。

  二、调用bind端口号为0,返回内核赋予的本地端口号。

  三、获取某套接字地址族。

  四、返回已通配地址bind的TCP服务的地址。

  

 getpeername返回某个套接字关联的外地协议地址;

  # include <sys/socket.h>

  int getpeername(int sockfd, struct sockaddr *peeraddr, socklen_t *addrlen);

  当一个服务器是由调用过accept的某进程经过exec执行程序时,能够经过getpeername获取客户身份。

相关文章
相关标签/搜索