代码思路:
1.Server端:
1.创建WSADATA变量
2.创建SOCKET套接字
发送消息
3.
1、WSADATA:一种数据结构,这种数据结构用于存放WSAStartup()函数调用后返回的Windows Sockets数据;
1.1、SOCKAET:创建套接字,相当于一个电话;
//地址族是什么?
- 通讯的基石是套接口,一个套接口是通讯的一端;
- 一个套接口可以理解位一个电话,有号码(地址)和数据完成通信,数据的接收依靠协议完成;
- 套接口在需要的时候创建,创建的时候需要指定域(domain),即所用的地址族(AF_INET 本地地址族、AF_INET6 网络地址族、AF_IRDA红外地址族;
- 在windows中 AF_INET 与 PF_INET 完全一样;
- 绑定所用的地址族sockaddr;
2、struct sockaddr 和 struct sockaddr_in 这两个结构体用于处理 网络通信的地址(目标地址/IP地址 和 端口)
区别:sockaddr 在头文件 #include <sys/socket.h>中 缺陷:把目标地址和端口混合了;如下:
struct sockaddr{
sa_family sin_family; //地址族;
char sa_data[14]; //14字节,包含套接字中的地址信息和端口信息
}
:sockaddr_in 在头文件 #include <netinet/in.h> 或 #include <arpa/inet.h> 中,该结构体把目标地址信息和端口信息存在两个变量中;
struct sockaddr_in{
sa_family_t sin_family; //地址族
uint16_t sin_port; //端口信息;16位TCP端口号
struct sin_addr; //目标地址信息;32位IP地址;
char sin_zero[8]; //不使用;
}
struct sin_addr{
In_addr_t s_addr; //32位IPV4地址;
}
3、send()函数
函数原型:send(int sockfd, const void *buf, size_t len, int flags);
函数功能:向对方发送数据,
参数介绍:
第一个参数:指定发送端套接字描述符;
第二个参数:指明一个存放应用程序要发送数据的缓冲区;
第三个参数:指明实际要发送的数据的字节数;
第四个参数:一般置0。
返回值:
发送成功:返回发送数据的字节数;
发送失败:返回-1 或 SOCKET_ERROR
4、recv函数
函数原型:int recv( SOCKET s, char FAR *buf, int len, int flags);
函数功能:接收数据,调用recv()函数会从接收socket的接收缓冲区读取数据存放到用户层的buffer里面;
参数介绍:第一个参数:指定接收端套接字描述符;
第二个参数:指明一个缓冲区,该缓冲区用来存放recv函数接收到的数据;
第三个参数:指明buf的长度;
第四个参数:一般置0;
返回值:情况1:成功执行时,返回接收到的字节数。
情况2:另一端已关闭则返回0。
情况3:失败返回-1,
情况4:SOCKER_ERROR等,错误原因有 内存不足等、
4.1 接收缓冲区和发送缓冲区与send() 和 recv()的关系;
原载:(4条消息) socket的send(),recv()以及缓冲区之间的关系_zj134_的博客-CSDN博客_recv缓冲区
接收缓冲区:对端发送来的数据会一直存放在socket的内核接收缓冲区中,进程调用recv()函数的时候,会从接收socket的接收缓冲区读取数据存放到用户层的buffer里面,然后返回
发送缓冲区:进程调用send()函数的时候,会把用户层buffer里面的数据拷贝的socket的发送缓冲区,之后函数就返回了。
( 也就是说send() 返回的时候,数据不一定发送了,只是完成了copy动作。)
5.connect()
函数原型:int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
函数功能:用于建立与指定socket的连接;
参数介绍:第一个参数 :socket文件描述符;
第二个参数:指定服务器端地址信息,含IP地址和端口号;
第三个参数:sizeof(addr) 大小;
返回值:成功返回0,失败返回-1;