今天看了C++下的网络编程,主要是socket编程,总结如下:
基于TCP连结的socket的流程;
服务器端:1.创建socket;2.将socket绑定到一个本地地址和端口上(bind);3.监听(listen),准备接受用户的连结请求;4.等待用户请求,当用户请求时,接受请求,返回一个新的对应此次连结的套接字accept;5.send和recv;6.返回,等待另一个客户请求;7.close;
客户端:1.创建套接字socket;2.想服务器发送请求(connect);3.send和recv;4.close;
基于UDP的面向无连接的socket编程就要简单的多:
服务器端:1.创建socket;2.bind绑定本地地址和端口;3.等待接受数据recvfrom;4.close;
客户端:1.创建socket;2.向服务器发送数据sendto;3.close;
几个相关的函数:
SOCKET socket(int af, int type, int protocol);
af为地址簇:AF_INET或者PF_INET;type为SOCK_STREAM(可靠的字节序列)或者SOCK_DGRAM(不可靠得数据报序列);protocol一般为0(即函数通过前两个参数自动选择协议类型);
int bind(SOCKET s, const struct sockaddr FAR *name, int namelen);
s为要绑定的套接字;name指向了套接字本地地址的信息;namelen指定了name指向的地址结构的长度;
sockaddr结构和sockaddr_in以及unix中的sockaddr_un的区别与联系?
(小小解释一下FAR关键字,就是使用两个字来保存指针和地址,这样就能实现远调用和远返回,跨段寻址的操作。如果使用Large或以上的模式编译,则FAR是缺省的。)
unsigned long inet_addr(const char FAR *cp);
用于将点分十进制的IP地址改为unsigned long类型。
int listen(SOCKET s , int backlog);
backlog为等待连结队列的最大长度。
SOCKET accept(SOCKET s ; struct sockaddr FAR* addr; int FAR * addrlen);
s是套接字描述符,该套接字必须设定为listen监听状态;addr是缓冲区指针,用于接受发出请求的客户端的ip地址;addrlen是地址信息长度;
int send(SOCKET s, const char FAR* buf, int len, int flags);
s是一个已经建立好连结的套接字描述符;buf指向一个存放传递数据的缓冲区;len是缓冲区的长度;flags是函数的行为参数,一般为0;
int recv(SOCKET s, char FAR * buf, int len ,flags);
s是建立好连结的接受的套接字;buf指向缓冲区用来保存数据的缓冲区;len缓冲区长度;flags函数参数,一般为0;
int connect(SOCKET s, const struct sockaddr FAR * name, int addrlen);
s是将在其上建立连结的套接字;name是要设定好的连结的服务器的地址信息;namelen指定服务器地址信息长度;
int recvfrom(SOCKET s, char FAR * buf, int len, int flags, struct sockaddr FAR * from, int FAR * fromlen);
s是准备接受数据的套接字;buf指向接受数据的缓冲区;len是缓冲区的长度;flags与send中的类似;from是发送数据方的地址信息。fromlen是from地址信息的长度。
int sendto(SOCKET s, char FAR * buf, int len, int flags, struct sockaddr FAR * to, int FAR * tolen);
类似recvfrom函数
htons和htonl函数:
主要是为了保证不同系统下的网络字节序一致。
u_short htons(u_short hostshort);
u_long htonl(u_long hostlong);
htons和htonl可以将主机字节序转换为TCP/IP网络字节序。htons为16位数值,htonl为32位数值。