更多精彩内容,请见:http://www.16boke.com
by zxy,Java/C++编程交流群:168424095
(1) 介绍
面向连接的Socket通信时基于TCP的。
TCP:Transmission Control Protocol 传输控制协议。TCP是一种面向连接(连接导向)的、可靠的、基于字节流的运输层(Transport layer)通信协议。
(2)通信流程
服务器和客户端进程实现面向连接的Socket通信的过程及调用的函数
服务器程序要先于客户端程序启动。
(3)函数的使用方法
(3.1)socket()函数用于创建与指定的服务器提供者绑定套接字,函数原型:
SOCKET socket(int af,//指定协议的地址家族,对于TCP/IP协议族,该参数置AF_INET
int type,//指定套接字的类型
int protocol//套接字使用的协议,一般取0,系统会根据套接字的类型决定应使用的传输层协议
);
函数执行成功,返回新Socket的句柄,失败,返回INVALID_SOCKET。
套接字类型:
SOCK_STREAM提供顺序、可靠、双向和面向连接的字节流数据传输机制,使用TCP
SOCK_DGRAM 支持无连接的数据报,使用UDP
SOCK_RAW 原始套接字,可以用于接收本机网卡上的数据帧或者数据包
#define IPPROTO_TCP 6 /* tcp */
#define IPPROTO_UDP 17 /* user datagram protocol */
举例:socket(AF_INET,SOCK_STREAM,IPPROTO_TCP)
IPPROTO_TCP指使用tcp协议
(3.2)bind()函数可以将本地地址与一个Socket绑定在一起,函数原型:
int bind()(
SOCKET s, //标识一个未绑定的Socket的描述符
const struct sockaddr FAR* name,//绑定到Sockets的sockaddr结构体地址
int namelen //参数name的长度
);
未发生错误返回0,否则返回SOCKET_ERROR
当使用Internet地址家族时,名称由地址家族、主机地址和端口号3部分组成。
ADDR_ANY,允许底层服务提供者使用任何适当的网络地址。
如:sockaddr_in addrSvr;
addrSvr.sin_family = AF_INET; //地址家族
addrSvr.sin_port = htons(port); //端口
addrSvr.sin_addr.s_addr = htonl(INADDR_ANY);//地址
(3.3)listen()函数可以将套接字设置为监听接入连接的状态,函数原型:
int listen(
SOCKET s,//指定一个已经绑定(执行了bind()函数)但尚未连接的套接字
int backlog //指定等待连接队列的最大长度
);
成功返回0,否则返回SOCKET_ERROR。
(3.4)accept()函数等待接受连接请求,函数原型:
SOCKET accept()(
SOCKET s,//通过调用listen()函数设置为监听状态的Socket
struct sockaddr FAR* addr;//输出参数,用于接收接入地址信息,若不关心接入地址,可用NULL
int FAR* addrlen//输出参数,指定接入地址的长度,也是可选参数
);
成功返回一个新建的Socket的句柄,该Socket用于实现服务器和客户端之间的通信,失败返回INVALID_SOCKET。
(3.5)recv()函数可以从已连接的Socket中接收数据,函数原型:
int recv(
SOCKET s,//已连接的Socket
char *buf,//用于接收数据的缓冲区
int len,//buf缓冲区的长度,单位为字节
int flags//用于影响函数的行为
);
flags的可选值:
MSG_PEEK数据将复制到缓冲区buf中,但并不从输入队列中移除这些数据
MSG_OOB处理带外(Out of Band,OOB)数据
成功,返回接收数据的字节数,连接已经关闭,返回0,否则返回SOCKET_ERROR。
(3.6)send()函数可以在已连接的Socket上发送数据,函数原型:
intsend(
SOCKETs,//已连接的Socket
constchar FAR* buf,//包含要发送数据的缓冲区
intlen,//buf缓冲区的长度,单位为字节
intflags//用于影响函数的行为
);
flags的可选值:
0指定该函数没有特殊的行为
MSG_DONTROUTE指定数据不选择路由
MSG_OOB从带外(Out of Band,OOB)发送数据
成功,返回发送数据的字节数,可能小于参数len中指定的数据长度,错误返回SOCKET_ERROR。
(3.7)closesocket()关闭一个Socket,释放其所占用的所有资源。函数原型:
intclosesocket(
SOCKETs//要关闭的Socket
)
没有错误,返回0,否则返回SOCKET_ERROR
(3.8)shutdown函数用于禁止在指定的Socket上发送和接收数据。
断开与Socket的连接有两种方式,优雅断开和中断断开。
(3.9)connect()函数用于建立到Socket的连接,该Socket必须处于监听状态,函数原型:
intconnect(
SOCKETs, //未连接的Socket句柄
conststruct sockaddr FAR* name,//指定要建立连接的Socket的名称
intnamelen//指定Socket名的长度
)
成功返回0,否则返回SOCKET_ERROR。
(4)其它
AF 表示ADDRESS FAMILY地址族PF 表示PROTOCOL FAMILY 协议族
Winsock2.h中
#define PF_INET AF_INET
所以在windows中AF_INET与PF_INET完全一样
ws2def.h中
#defineAF_INET 2 // internetwork: UDP, TCP, etc.
(4.2)例子:客户端循环向服务器发送字符串,并显示反馈信息。发送"quit"将使服务器程序退出,同时客户端程序自身也将退出
源码下载:
更多精彩内容,请见:http://www.16boke.com