代码的整体逻辑:
UDP服务端
:udpServer.cc(服务端的调用),udpServer.hpp(服务端的实现)
UDP客户端
:udpClient.cc(客户端的调用),udpClient.hpp(客户端的实现)
1.udp服务端
服务端:1.初始化服务器 2.启动服务器
作为一款服务器:要有自己的服务端口号uint16_t _port,同时网络服务器需要有对应的string _ip地址,文件描述符_sockfd:进行各种各样的数据通信,在类内进行读写操作。对于ip地址的类型:字符串型只在我们用户层作为参数传递,传递的IP格式为" 127.0.0.1 "这种格式的IP称之为“点分十进制"IP,这样的IP是字符串,可读性高,但是仅仅在我们用户层使用,但是在网络通信的过程中IP是需要转换为 uint32_t 类型,这时候需要调用相关的接口转换为网络通信使用的的IP风格。
一.初始化服务器
初始化服务器服务器包括:创建套接字和绑定端口号和IP
参数据数domain:域,未来套接字是进行网络通信还是本地通信,主要使用下面这两种 :
AF_UNIX, AF_LOCAL
AF_INET
参数type:套接字提供服务的类型,如SOCK_STREAM:流式服务TCP策略,SOCK_DGRAM:数据报服务,UDP策略参数protocol:缺省为0,可由前两个类型由系统决定并填充
返回值:失败返回-1,成功返回文件描述符
绑定端口号和IP的接口:
参数sockfd:文件描述符进行通信,也就是调用socket的返回值
参数addr:利用struct sockaddr_in强转
参数addrlen:结构体的长度
返回值:成功返回0,失败返回-1
这里需要定义一个sockaddr_in
结构体并填充数据,然后传递进去
sockaddr_in结构体的内部成员:
struct sockaddr_in
{
__SOCKADDR_COMMON (sin_);
in_port_t sin_port; /* Port number. */
struct in_addr sin_addr; /* Internet address. */
/* Pad to size of `struct sockaddr'. */
unsigned char sin_zero[sizeof (struct sockaddr) -
__SOCKADDR_COMMON_SIZE -
sizeof (in_port_t) -
sizeof (struct in_addr)];
};
在结构体内部:首先填充协议家族,给别人发消息未来还要从对方接收消息,所以需要将自己的port和IP填充进去,port需要由主机序列转为网络序列,因为初始传来的ip是string类型的所以IP需要由点分十进制转为整数然后再转为网络序列。
一款网络服务器不建议指明一个IP,也就是不要显示地绑定IP,服务器IP可能不止一个,如果只绑定一个明确的IP,最终的数据可能用别的IP来访问端口号,访问不出来,所以真实的服务器IP一般采用INADDR_ANY(全0,任意地址)代表任意地址bind
初始化服务器的代码:
void initServer()
{
//1.创建套接字
_sockfd = socket(AF_INET,SOCK_DGRAM,0);
if(_sockfd == -1)
{