Linux受到广泛运用,一个重要的原因就是其强大的网络功能。SOCKET用于在两个基于TCP/IP协议的应用程序之间相互通信。最早出现在UNIX系统中,是UNIX系统主要的信息传递方式。在WINDOWS系统中,SOCKET称为WINSOCK。
两个基本概念:客户方和服务方。当两个应用之间需要采用SOCKET通信时,首先需要在两个应用之间(可能位于同一台机器,也可能位于不同的机器)建立SOCKET连接,发起呼叫连接请求的一方为客户方,接受呼叫连接请求的一方成为服务方。客户方和服务方是相对的,同一个应用可以是客户方,也可以是服务方。
所谓socket通常也称作“套接字”,应用程序通常通过“套接字”向网络发出请求或者应答网络请求。在Internet上有很多这样的主机,这些主机一般运行了多个服务软件,同时提供几种服务。每种服务都打开一个Socket,并绑定到一个端口上,不同的端口对应于不同的服务 。比如:http 80, ftp 21
sockets和底层的文件描述符非常类似(可以在sockets里使用read()和write()函数),尽管建立一个socket比打开,读取和写入一个文件更为麻烦,但这是由于网络连接比单纯的本地硬盘的读写复杂的多所造成的。通常,sockets用来实现客户机/服务器对。服务器的任务是监听某个特定的端口,当接收到客户端的服务请求时完成相应的服务;客户机的任务是请求服务器完成事先设定好的服务。
和打电话类似
常用函数
Int socket(int af, int type, int protocol)
Eg: sockfd = socket(AF_INET, SOCK_STREAM, 0)
-1 错误 0 成功
Int bind(int sockfd, struct sockaddr *name, int namelen)
Eg: bind(sockfd, (struct sockaddr*)&serv_addr, sizeof(struct sockaddr))
connect()
Int connect(int sockfd, struct sockaddr *serv_addr, int addrlen)
listen ()
Int listen(int sockfd, int backlog)
返回失败-1,否则为新句柄
accept()
Int accept(int sockfd, void *addr, int *addrlen)
接发函数(SOCK_STREAM):
Int send(int sock, const void *msg, int len, int flags)
Int recv(int sock, const void *buf, int len, int flags)接发函数(SOCK_DGRAM):
Int sendto(int sock, const void *msg, int len, int flags
Const struct sockaddr *to, int tolen)
Int recvfrom(int sock, const void *buf, int len, int flags, const struct sockaddr *from, int fromlen)
Close() 和shutdown()
Int close(int sockfd)
Int shutdown (int sockfd, int how)
1 不允许再收了
2 不允许再发了
3不允许收发了(同close)
和send,recv差不多,少了个参数
int select(int nfds, fd_set *readset, fd_set *writeset, fd_set* exceptset, struct tim *timeout);
功能:测试指定的fd可读?可写?有异常条件待处理?适合同时监听多个不同请求
fd_set(它比较重要所以先介绍一下)是一组文件描述字(fd)的集合,它用一位来表示一个fd 。
select()函数主要是建立在fd_set类型的基础上的。
4种操作
FD_ZERO(&set); 清0
FD_SET(fd, &set); 置某位为1
FD_CLR(fd, &set); 删除一个文件描述符
FD_ISSET(fd, &set); 测试指定的文件描述符是否在该集合中。
使用select函数的过程一般是: