socket
在使用socket进行网络通信时必须先导入相关的库文件,同时初始化相关的库
//导入头文件
#include<winsock2.h>
#pragma comment(lib, "ws2_32.lib")
//初始化库
WSAStartup(MAKEWORD(2, 2), &wsaData);
创建socket
创建socket用于在设备上监听连接请求,接受数据,发送数据。需要调用函数socket
参数有三:
- 使用的地址类型,当前情况下地址类型有两种IPV4以及IPV6,在winsock2中使用AF_INET表示ipv4,AF_INET6表示ipv6的地址,
- 使用的套接字类型,一般情况下,我们使用流式套接字或者数据报协议进行通讯,winsock2中使用SOCK_STREAM表示流式套接字,SOCK_DGRAM表示数据包套接字
- 使用的传输层协议,需要根据前两个参数设置,一般配置为AF_INET + SOCK_STREAM + IPPROTO_TCP 或者 AF_INET + SOCK_DGRAM + IPPROTO_UDP,在新手期这两组配置就够我们玩了
如果不出意外那么我们的第一个套接字就创建出来了,此时该套接字还不能使用,需要和我们的设备进行绑定
绑定地址bind函数
在网络中要想定位到一个服务需要两个参数,IP和端口,IP定位到你的电脑,端口定位到运行在你电脑上的应用,在bind函数中使用sockaddr结构来表示一个地址,但是不严格要求数据类型必须是sockaddr,只要第一个u_short表示地址类型,且长度为指定的长度即可,在地址类型为IPV4的前提下,我们更倾向于使用sockaddr_in来表示地址。
struct sockaddr_in{
short sin_family;//地址类型,一般就是AF_INET,
u_short sin_port;//端口
struct in_addr sin_addr;//IP地址
}
在winsock2中使用in_addr来表示IPV4的地址,我们一般不会手写in_addr类型的结构体,而是通过特定的函数(如:inet_addr)将我们易读的点分十进制数据转化为in_addr类型的数据,更加准确的说是转化为in_addr.S_un.S_addr类型的数据,一般就使用in_addr.Sun.S_addr来表示ip地址
struct in_addr {
union {
struct {
u_char s_b1;
u_char s_b2;
u_char s_b3;
u_char s_b4;
} S_un_b;
struct {
u_short s_w1;
u_short s_w2;
} S_un_w;
u_long S_addr;
} S_un;
};
绑定地址:bind(socket, (SOCKADDR* )&地址,地址所占的字节数)
等待别人的连接 listen
绑定地址以后那么你再互联网上就有了一个身份标识,这个标识唯一指向你,此时别人就可以通过这个唯一标识访问你了(如果是局域网,可能需要进行端口转发)。
listen(socket, 最大连接数)
获取连接
有人访问了你,但是不是任何人都能访问你。
int len = sizeof(地址)
SOCKET clientSocket = accept(socket, &地址,&len)
用户访问你以后,地址就会保存用户的地址,你可以根据地址决定是否回应请求。clientSocke也是socket类型的专门用于和用户进行通讯。
获取数据
char buf[1024];
int len = recv(socket, buf, sizeof(buf), 0)
接受数据保存到buf当中,len表示数据所占的字节数据,最后以外给0即可
发送数据
char buf[1024] = "hello world";
int len = send(socket, buf, strlen(buf), 0)
//dataLen表示需要发送的数据的长度
发送数据,并返回发送的数据量