基本socket函数和C/S流程

主要讲解一个完整TCP客户、服务器程序所需要的基本套接字函数。所需函数如图4-1所示(图片来源于linux一站式编程):


一、基本函数

1. socket函数

socket可以看成是用户进程与内核网络协议栈的编程接口。
socket不仅可以用于本机的进程间通信,在进程间通信,用共享内存的方式是最快的,但是基于socket的通信移植性较好,在目前分布式几乎都是用的基于socket的进程间通信还可以用于网络上不同主机的进程间通信。

#include <sys/socket.h>

原型: int socket(int family, int type, int protocal);

参数:

family:AF_INET,AF_INET6,AF_LOCAL。。。

type:  SOCK_STREAM,SOCK_DGRAM。。。

protocal: 正常为0。

2. connect函数

用来建立与TCP服务器端的连接,3次握手的开始。

原型:

int connect(int sockfd, const struct socket *servaddr, socklen_t  len);

参数:

sockfd:socket()返回值

servaddr:服务器套接字地址

len:sruct长度

3. bind函数

服务器端绑定众所周知的端口号,用于客户端发起连接

原型:

int bind(int sockfd, const struct socket *myaddr, socklen_t  len);

参数:

如上

4. listen函数

listen函数不是阻塞式的,它只是告诉内核打开某端口监听,真正“监听”的是内核,而不是我们的服务端程序。
listen把第一个参数套接字转换成监听套接字

(1) 主动套接字,导致套接字状态CLOSED到LISTEN状态

(2)指定套接字排队的最大连接数(两个队列之和)

原型:

int listen(int socket, int backlog);

参数:

backlog: 两个队列之和,如下图所示


$ man listen看看,里面有一段话:

If the backlog argument is greater than the value in /proc/sys/net/core/somaxconn, then it
is silently truncated to that value; the default value in this file is 128. In kernels
before 2.4.25, this limit was a hard coded value, SOMAXCONN, with the value 128.

用http://www.cnblogs.com/xiaouisme/archive/2012/07/08/2581810.html这篇文章的结果:

当传参backlog的值< somaxconn时,已完成连结队列的数量最多就是backlog的值。未完成连结队列数量在10左右摇摆。

当传参backlog的值 >= somaxconn时,已完成连结队列的数量最多就是somaxconn。未完成连结队列数量同上。

结论噢:在ubuntu12.04上,backlog的值就是已完成连结队列的值,此值受限于somaxconn。

确切的说backlog应该是最大已经完成的连接数

5. accept函数

从已经连接的队列头取出一个已经完成的连接。

原型:

int accept(int sockfd, struct sockaddr *cliaddr, socklen_t *addrlen)

参数:

cliaddr: 对端的协议地址,可以为空指针,表示对客户端信息不敢兴趣

addrlen: 值结果传递,struct的字节数

说明:

返回值为内核生成胡全新套接字描述符,表示与客户端的tcp连接,可以对该描述符读写。

6.close函数

关闭套接字,默认行为套接字标记为关闭, 立即返回(非阻塞)到调用进程,套接字描述符不能write,read。

TCP将尝试发送已经在缓冲区中的数据,可以用SO_LINGER改变这一行为。

原型:

int close(int sockfd) //成功返回0,否则返回-1

说明:

close函数只是相应的描述符引用计数减一。因此在并发服务器中,子进程中要关闭listendfd。 

for(; ; ){
     connfd = accept(...);
     if((pid == fork()) == 0){
	close(listenfd);  //子进程关闭监听描述符自作主张
	doit(connfd);	
	close(connfd);     
     }
     close(connfd);//父进程关闭描述符
}
7. getsockname和getpeername函数

获取对应的描述符协议地址,必须是已经连接的描述符。

原型:

int getsockname(int fd, struct sockaddr * addr, socklen_t *addrlen);

int getpeername(int fd, struct sockaddr *addr, socklen_t *addrlen);


 







评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值