一、linux下使用套接字
1.TCP套接字(安装电话机)
#include <sys/socket.h> //linux下使用
//#include <WinSock2.h> //windows下使用
int socket(int domain, int type, int protocol);
(1)第一个参数代表套接字使用的协议族:PF_INET(iPv4)、PF_INET6(iPv6)、PF_LOCAL(本地通信UNIX协议族)等;
理论上建立socket时是指定协议,应该用PF_xxxx,设置地址时应该用AF_xxxx。
(2)第二个参数代表套接字类型:面向连接(SOCK_STREAM)、面向消息(SOCK_DGRAM);
(3)第三个参数一般为0,除非前两个参数仍然无法确定指定的传输协议。
2.调用bind函数(为套接字分配地址信息IP:PORT)
#include <sys/socket.h> //linux下使用
//#include <WinSock2.h> //windows下使用
int bind(int sockfd, struct sockaddr *myaddr, socklen_t addrlen);
3.调用listen函数(连接电话线)
#include <sys/socket.h> //linux下使用
//#include <WinSock2.h> //windows下使用
int listen(int sockfd, int backlog);
4.调用accept函数(拿起话筒)
#include <sys/socket.h> //linux下使用
//#include <WinSock2.h> //windows下使用
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
5.网络编程中接受连接请求的套接字创建流程:
(1)调用socket函数创建套接字;
(2)调用bind函数分配IP地址和端口;
(3)调用listen函数转为可接受请求状态;
(4)调用accept函数受理连接请求。
6.服务器端创建(监听)服务器端套接字的流程:
(1)调用socket函数创建套接字;
(2)调用connect函数向服务器端发送连接请求。
#include <sys/socket.h> //linux下使用
//#include <WinSock2.h> //windows下使用
int connect(int sockfd, struct sockaddr *ser_addr, socklen_t addrlen);
二、windows下使用
1.Winsock初始化
#include <WinSock2.h>
int WSAStartup(WORD wVersionRequested, LPWSADATA lpWSAData);
//注销:
int WSACleanup(void);
//常见用法:
WSADATA wsaData;
if(WSAStartup(MAKEWORD(2,2), &wsaData)!=0)
ErrorHandling("WSAStartup() erroe!");
WSACleanup();
2.套接字
#include <WinSock2.h>
SOCKET socket(int af, int type, int protocol);
(1)第一个参数代表套接字使用的协议族:PF_INET(iPv4)、PF_INET6(iPv6)、PF_LOCAL(本地通信UNIX协议族)等;
相关头文件中的定义:AF = Address Family
PF = Protocol Family
AF_INET = PF_INET
在windows中的Winsock2.h中
#define AF_INET 0
#define PF_INET AF_INET
所以在windows中AF_INET与PF_INET完全一样。
(2)第二个参数代表套接字类型:面向连接(SOCK_STREAM)、面向消息(SOCK_DGRAM);
(3)第三个参数一般为0,除非前两个参数仍然无法确定指定的传输协议。
3.分配IP和端口号
#include <WinSock2.h>
int bind(SOCKET s,const struct sockaddr *name, int namelen);
4.连通与监听
#include <WinSock2.h>
int listen(SOCKET s,int backlog);
5.连接(接收)和发送
#include <WinSock2.h>
SOCKET accept(SOCKET s, struct sockaddr *addr, int * addrlen);
int connect(SOCKET s, const struct sockaddr * name, int namelen);
6.关闭套接字
#include <WinSock2.h>
int closesocket(SOCKET s);
7.基于windows的I/O函数
在linux中文件I/O和套接字的I/O共用一个系统,而在windows中,这是两个不同的系统,所以用flag来区分。
#include <WinSock2.h>
//发送端传输函数
int send(SOCKET s, const char *buf, int len, int flags);
//接收端传输函数
int recv(SOCKET s, const char *buf, int len, int flags);
三、网络字节序
不同的CPU有不同的字节序类型,这些字节序是指 整数 在内存中保存的顺序,这个叫做 主机序。
最常见的有两种:
1.Little endian:将低序字节存储在起始地址
2.Big endian:将高序字节存储在起始地址
网络字节顺序是TCP/IP中规定好的一种数据表示格式,它与具体的CPU类型、操作系统等无关,从而可以保证数据在不同主机之间传输时能够被正确解释。网络字节顺序采用big endian排序方式。
htons() 把unsigned short类型从主机序转换到网络序;
htonl() 把unsigned long类型从主机序转换到网络序;
ntohs() 把unsigned short类型从网络序转换到主机序;
ntohl() 把unsigned long类型从网络序转换到主机序。