本文是续上文关于基于TCP套接字实现的简单Demo后进行
套接字基本知识的讲解.
可能文中有一些术语使用不太准确,但作为我自己的理解,尽量以
通俗的语言为大家讲解.
套接字即Socket.用于在进程之间进行通信.
当然进程通信的方式多种多样,但是Socket
在进程通信的使用却十分广泛.
当然这里有几个概念需要区分.
http,socket,tcp/ip之间的关系.
大家都知道,现在互联网中广泛
使用TCP/IP协议,如果你想要在
当前的网络中传输数据,那么就
必须遵守TCP/IP协议准则,而http
是属于应用层面的协议,与FTP,
Telnet等协议类似,当然还有用户
自定义的一些协议.这些协议的目
的是对TCP/IP传输的数据进行解
析.
而Socket作为进程通信的手段
也是基于TCP/IP协议的,然而我
们要实现应用层协议或者实现
自己的协议,我们必须使用Socket
提供的借口才能使这些协议数据
是通过TCP/IP协议准则传输的.
总之,TCP/IP是根本的准则.通过Socket
我们才能利用TCP/IP协议.而应用层协议
则提供我们对Socket传输的数据进行封包
和解析的标准.
对于一个套接字,我们可以看做是一条电话线路,
而这条线路的建立则是基于TCP/IP标准的,而电
话线两端就是我们通信的双方.
那么一个套接字如何标识一个链接或者说如何
识别通信的双方呢.
那就是套接字三元组: 套接字=协议+端口+IP
套接字分类:
根据使用的协议类型不同,套接字分为三类.
1.TCP套接字
2.UDP套接字
3.原始套接字.
其中使用较为广泛的是TCP套接字和UDP套接字.
而原始套接字是基于数据链路层协议.这里不作介绍.
了解TCP协议都知道,TCP是面向链接的协议,在通信之前
在通信双方要先进行“三次握手”成功建立连接后才能进行
通信,所以其传输数据时可靠的,然而正是因为此原因,使得
TCP的套接字传输效率要低一些.
而UDP套接字是面向无连接,但是不提供可靠的数据传
输.这点说明在传输的过程中有可能出现数据丢失,但是正
是在传输之前不需要建议连接,这种数据传输的方式要高
于TCP传输方式.
原始套接字在这里也不作介绍,因为我也很少接触.
阻塞与非阻塞:
关于Socket字的方式 有两类
1.阻塞方式
2.非阻塞方式.
我们可以简单的这样理解,阻塞方式是
当建立多个套接字连接后,多个套接字
同时传输和接受数据的方式可以成为
非阻塞方式.
而相反,当多个套接字进行连接后,只有
只有当一个套接字完成接或者发数据
的方式后才能进行下一个套接字的收
或者发数据的动作成为阻塞方式.
显然阻塞方式要比非阻塞方式复杂.
但是在实际应用中大多使用阻塞方式
进行数据传输.
阻塞方式大多使用多线程的方式实现.
套接字地址结构:
struct sockaddr_in
{
short sin_family;//AF_INET
u_short sin_port;//16位端口号,网络字节顺序
struct in_addr sin_addr;//32位IP地址,网络字节顺序
char sin_zero[8];//保留
}
一个套接字地址结构就将套接字三元组完整的定义了.
下面介绍TCP套接字的流程.
流程图如下:
不难看出我们可以对TCP套接字的服务器端和客户端用到的API进行总结:
server:
1.加载套接字库,进行套接字库初始化.这样我们才能使用需要的套接字.
2.创建套接字:
格式:SOCKET PASCAL FAR socket(int af,int type,int procotol); 参数:af: 通信发生的区域 type: 要建立的套接字类型 procotol: 使用的特定协议
3.初始化服务器端套接字地址
SOCKADDR_IN addrSrv; addrSrv.sin_addr.S_un.S_addr = htonl(INADDR_ANY); addrSrv.sin_family = AF_INET; addrSrv.sin_port = htons(6000)
;
4.将套接字号和服务器端套接字进行绑定
功能:将套接字地址与所创建的套接字号联系起来。格式:int PASCAL FAR bind(SOCKET s,const struct sockaddr FAR * name,int namelen); 参数:s: 是由socket()调用返回的并且未作连接的套接字描述符(套接字号)。 其它:没有错误,bind()返回0,否则SOCKET_ERROR
5.接受来自客户端的连接请求
SOCKET PASCAL FAR accept(SOCKET s,struct sockaddr FAR * name,int FAR * addrlen); 参数:同上
6.数据发送和接受
功能:数据的发送与接收 格式:int PASCAL FAR send(SOCKET s,const char FAR * buf,int len,int flags); int PASCAL FAR recv(SOCKET s,const char FAR * buf,int len,int flags); 参数:buf:指向存有传输数据的缓冲区的指针
7.传输结束,关闭套接字
关闭套接字――closesocket() 功能:关闭套接字s 格式:BOOL PASCAL FAR closesocket(SOCKET s);
Client:
1.建立客户端套接字
同上
2.将客户端套接字和服务器端地址接受绑定
同上
3.连接服务器
int PASCAL FAR connect(SOCKET s,const struct sockaddr FAR * name,int namelen);
4.进行数据发送和接受
同上
5.关闭套接字
同上
至此,关于Window套接字就介绍完了,虽然不尽详尽,但是我尽可能给大家讲清楚一些
基本概念,和一些基本流程.在完全理解后,读者可以参照基于TCP套接字实现的简单Demo
一文写一些自己的套接字小Demo.至于深入部分,只有靠大家自己了,我也是小鸟正在努力的.