赞
踩
Socket简介
HTTP/HTTPS协议
Socket编程实验
Socket API
BSD Socket API
不是为每个应用程序定义接口,而是提供最基本的通信功能
对上层提供统一的调用接口,支持丰富的上层应用开发
//=====================BSD Socket API=======================
socket(domain,type,proto);
close(sockfd);
bind(sockfd,addr,addrlen);
//=============Datagram(Connectionless)======================
sendto(sockfd,buf,len,flags,dest_aaddr,addrlen);
recvfrom(sockfd,buf,len,flags,src_addr,addrlen);
//=============Stream(Connection-oriented)===================
listen(sockfd,backlog);
accept(sockfd,addr,&addrlen);
connect(sockfd,addr,addren);
send(sockfd,buf,len,flags);
recv(sockfd,&buf,len,flags);
Socket调用流程
数据收发两端都需要建立socket文件描述符
# include<sys/socket.h>
int socket(int domain,int type,int protocol);
//在Linux 下使用<sys/socket.h>头文件中的socket()函数来创建套接字,原型为
int socket(int af,int type,int protocol);
1) af为地址族(Address Family),也就是IP地址类型,常用的有 AF_INET 和AF_INET6。
AF是"address Family"的简写,INET是"Inetnet"的简写。AF_INET表示IPv4地址,例如
127.0.0.1;AF_INET6表示IPv6地址,例如 1030::C9B4:FF12:48AA:1A2B.
127.0.0.1是一个特殊的IP地址,表示本机地址
2) type为数据传输方式/套接字类型,常用的有 SOCK_STREAM (流格式套接字/面向连接的套接字)和 SOCK_DGRAM (数据报套接字/无连接的套接字)。
3) protocol 表示传输协议,常用的有 IPPROTO_TCP 和 IPPTOTO_UDP, 分别表示 TCP 传输协议和 UDP传输协议。
int socket(IP地址类型(IPv4/IPv6), 数据传输方式(SOCK_STREAM / SOCK_DGRAM), 传输协议(IPPROTO_TCP/IPPTOTO_UDP))
第三个参数,一般情况下有了af 和 type 两个参数就可以创建套接字了,操作系统会自动推演出协议类型,除非遇到: 有两种不同的协议支持同一种地址类型和数据传输类型。如果不指明,操作系统无法自动推演。
/* 使用IPv4地址,参数af的值为 AF_INET ,如果使用 SOCK_STREAM 传输数据,那么满足
这两个条件的协议只有 TCP,因此可以这样调用 socket()函数: */
int tcp_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
/* 使用SOCK_DRGAM 传输方式,满足这两个条件的协议只有 UDP*/
int udp_socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
/* 上面两种情况都只有一种协议满足条件,可以将 protocol 的值设为0,系统会自动推演出应该使用什么协议 */
int tcp_socket = socket(AF_INET, SOCK_STREAM, 0); // 创建TCP套接字
int udp_socket = socket(AF_INET, SOCK_DRGAM, 0); // 创建UDP套接字
将 address 指向的 sockaddr 结构体中描述的一些属性(IP地址、端口号、地址簇) 与 socket套接字绑定,也叫给套接字命名。
调用bind()后,就为 sockfd 套接字关联了一个相应的地址与端口号,即发送到该地址该端口的数据可以通过 sockfd 读取和使用。当然也可通过该 sockfd 发送数据到指定目的。
对于 Server, bind()是必须要做的事情,服务器启动时需要绑定指定的端口来提供服务(以便于客户向指定的端口发送请求),对于服务器 sockfd 绑定地址,一般而言将 IP 地址复制为 INADDR_ANY(该宏值为 0),即无论发送到系统中的哪个 IP 地址(当服务器有多张网卡时会有多个 IP 地址)的请求都采用该 sockfd 来处理,而无需指定固定 IP。
对于 Client , 一般而言无需主动调用 bind(),一切由操作系统来完成。在发送数据前,操作系统会为套接字随机分配一个可用的端口,同时将该套接字和本地地址信息绑定。
只需要被动建立连接一方进行绑定(bind)
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
sockfd : Socket 文件描述符
addr : 需要绑定的地址和端口
addrlen : 地址和端口数据结构的长度
struct sockaddr_in server;
server.sin_family = AF_INET;
server.sin_addr.s_addr = INADDR_ANY;
server.sin_port = htons(80); // 主机字节序调整为网络字节序,80端口是http协议
bind(sockfd,(struct sockaddr *)&server, sizeof(server));
只在被动建立连接一方进行监听,等待新的连接请求
int listen(int sockfd, int backlog)
// backlog 指最多允许多少个客户连接到服务器,它的值至少为1。收到连接请求后,这些请求需要排队,如果队列满,就拒绝请求。
sockfd: 之前建立的文件描述符
backlog: 可以理解为待处理请求的最大数目
listen(sockfd,128);
accept() 接收一个套接字中已建立的连接
# include<sys/types.h>
# include<sys/socket.h>
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
accept()系统调用主要用在基于连接的套接字类型 ,比如 SOCK_STREAM 和 SOCK_SEQPACKET。**它提取出所监听套接字的等待连接队列中第一个连接请求,创建一个新的套接字,并返回指向该套接字的文件描述符。**新建立的套接字不在监听状态,原来所监听的套接字也不受该系统调用的影响。新建立的套接字准备发送send()和接收数据recv()。
参数
sockfd, 利用系统调用socket()建立的套接字描述符,通过bind()绑定到一个本地地址(一般为服务器的套接字),并且通过listen()一直在监听连接。
addr : 指向struct sockaddr 的指针,该结构用**通讯层服务器对等套接字的地址(一般为客户端地址)**填写,返回地址 addr 的确切格式由套接字的地址类别(比如TCP或者UDP)决定;若addr为NULL,没有有效地址填写,这种情况下,addrlen也不使用,应该置为 NULL;
addr 是个指向局部数据结构 sockaddr_in 的指针,这就是要求接入的信息本地的套接字(地址和指针)。
addrlen: 一个值结果参数,调用函数必须初始化为包含 addr 所指向结构大小的数值,函数返回时包含对等地址(一般为服务器地址)的实际数值;
addrlen 是个局部整型变量,设置为sizeof(struct sockaddr_in)
如果队列中没有等待的连接,套接字也没有被标记为Non-blocking,accept()会阻塞调用函数直到连接出现; 如果套接字被标记为 Non-blocking,队列中也没有等待的连接, accept()返回错误
EAGAIN 或 WWOULDBLOCK。
为了在套接字中有到来的连接时得到通知,可以使用select() 或 poll() 。当尝试建立新连接时,系统发送一个可读事件,然后调用accept()为该连接获取套接字。另一种方法是,当套接字中有连接到来时设定套接字发送SIGIO信号。
返回值:成功:返回非负整数,该整数是接收到套接字的描述符;出错返回-1,相应设定全局变量errno。
被动建立连接一方需要显式的接收连接请求
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
sockfd: 之前建立的 socket文件描述符
addr : 用于存储对端网络地址的数据结构
addrlen : 指定 addr 大小
返回值为该连接对应的文件描述符,以后收发数据都使用该文件描述符:
int csock = accept(sockfd, (struct sockaddr_in *)&caddr, &clen);
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。