免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1020 | 回复: 0
打印 上一主题 下一主题

《Unix网络编程 - 基本TCP套接口编程》 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2007-06-28 19:57 |只看该作者 |倒序浏览

1_ 建立一个与TCP服务器的连接:connect函数,

int connect(int sockfd, const struct sockaddr * servaddr, socklen_t addrlen);
2_connect的几种错误返回类型:
   ·TCP客户没有收到SYN分节的响应,返回ETIMEDOUT;
   ·对客户的SYN相应是RESET,称为硬错,返回ECONNREFUSED;
   ·客户发出的SYN引发了目的不可达的ICMP错误,返回EHOSTUNREACH或ENETUNREACH。
3_bind函数为套接口分配一个本地协议地址:

int bind(int sockfd, const struct sockaddr * servaddr, socklen_t addrlen);
对于TCP,bind函数用于指定一个IP地址&一个端口号,也可以两者都不指定,让内核为其分配,sin_addr为通配地址htonl(INADDR_ANY),sin_prot为0时,将由内核为进程选择IP和端口。
4_如果让内核为进程选择端口,端口号显然无法从const结构中返回,要获取此分配端口号必须调用getsockname。
5_另有一个技术是对于运行单个服务器但捆绑通配地址,连接请求到达时,调用getsockname得到客户的目的IP地址,然后服务器根据这个IP地址来处理请求。
6_linsten函数仅被服务器调用,

int listen(int sockfd, int backlog);
完成两件事情:
   ·将未连接的套接口转换成被动套接口,指示内核应接收指向此套接口的连接请求。导致套接口从CLOSED状态到LISTEN状态;
   ·规定内核为此套接口排队的最大连接数。
一般来讲,此函数应该在调用了socket&bind之后,在调用accept之前进行调用。
7_对于给定的监听套接口,内核必须为它维护两个队列:
   ·未完成连接的队列:正在等待完成TCP三路握手的SYN分节;这些套接口都处于SYN_RCVD状态;
   ·已完成连接的队列:已完成三路握手的套接口,处于ESTABLISH状态。
而backlog为两个队列长度总和,因此,对于backlog,网络程序员们常常在程序中设定缺省值,同时允许通过命令行的形式进行修改。
8_accept函数从已完成队列取下一个已完成的连接。若队列空,进程睡眠(或阻塞):

int accept(int sockfd, struct sockaddr * cliaddr, socklen_t *addrlen);
    如果accept成功,返回一个由内核分配的全新描述字(已连接套接口描述字),代表与客户的TCP连接。而此前的描述字(由socket函数生成)称为监听套接口描述字。两者的区别非常重要:一个服务器常常只生成一个监听套接口且一直存在,直到该服务器关闭;然而内核为每个已连接的客户创建一个已连接套接口,当服务器完成某服务时,即可关闭。
    该函数最多返回三个值:返回一个即可能是已连接套接口描述字,也可能错误指示的整数;一个客户进程的协议地址(由cliaddr所指)以及该地址的大小(由addrlen所指)。

9_fork()函数是UNIX中派生新进程的唯一办法,它调用一次返回两次,在调用进程(父)返回一次,返回子进程的ID号;在子进程返回一次,返回0。子进程可以通过getpid来得到父进程的ID,而父进程则需要通过记住fork的返回值来跟踪它所有子进程。
10_进程在调用fork之前打开的描述字在fork返回之后都是共享的。父进程调用accept,然后调用fork,这样已连接的套接口就在父子进程之间共享,一般情况下,子进程将读写套接口,而父进程则关闭已连接的套接口。
11_以文件形式存储的可执行文件在UINX上执行的唯一方法是通过一个现有进程调用exec,用新程序代替当前的映象,进程ID并不发生改变。
12_UNIX下写并发服务器的一个简单方法是为每个客户fork一个新进程,即父进程accept后,fork子进程,然后由子进程读写已连接的套接口,而父进程则关闭已连接套接口,继续等待另一个连接。
    这个过程中,由于每个文件&套接口都有一个访问计数,在父进程fork后,相对应已连接套接口访问计数为2,不会因为父进程关闭而完全关闭,即不会发送四分组连接终止序列。如果真正希望发送FIN分节,可以调用shutdown。
13_服务器在子进程连接到已连接套接口时,关闭已连接套接口是非常有必要的:否则会耗尽内核可用描述字,并且指示该TCP连接无法真正Close(访问计数至少为1)。
14_getsockname返回与套接口关联的本地协议地址,getpeername返回与套接口关联的远程协议地址。

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

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

getsockname返回内核分配给进程的IP和端口号;Telnet服务器调用的第一个函数就是getpeername由此获得客户的IP&端口号。


本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u1/42528/showart_330522.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP