udp客户端和服务器代码,支持ipv6。
2016-09-13 12:01
369 查看
getaddrinfo这个函数隐藏了ipv4和ipv6的具体细节,强烈推荐使用。设置hints.ai_family = AF_UNSPEC后,getaddrinfo可以根据ip地址自动判断是ipv4还是ipv6。当然也可以使用hints.ai_family = AF_INET6直接指定为ipv6。
同时getnameinfo也是同时支持ipv4和ipv6的函数,建议使用。
服务器代码:
客户端代码
同时getnameinfo也是同时支持ipv4和ipv6的函数,建议使用。
服务器代码:
#include "stdafx.h" #include <winsock2.h> #include <iostream> #include <Ws2tcpip.h> #pragma comment(lib, "ws2_32.lib") int main() { WSADATA wd{}; auto err = WSAStartup(MAKEWORD(2, 2), &wd); if (0 != err) { return 0; } addrinfo *result = nullptr; addrinfo hints = {}; hints.ai_socktype = SOCK_DGRAM; //数据报 hints.ai_protocol = IPPROTO_UDP; //udp hints.ai_family = AF_UNSPEC; //协议无关 hints.ai_flags = AI_PASSIVE; //用于服务端bind,用于bind这个参数必须设置 //第一个参数为nullptr或0.0.0.0,表示监听本地所有网卡数据,0.0.0.0表示只能为ipv4。 //或者hints.ai_family = AF_INET;也表示使用ipv4 auto dwRetval = getaddrinfo("0.0.0.0" /*本地所有网卡,ipv4*/, "3000"/*端口号为3000*/, &hints, &result); if (0 != dwRetval) { return 0; } auto s = socket(result->ai_family, result->ai_socktype, result->ai_protocol); if (INVALID_SOCKET == s) { return 0; } err = bind(s, result->ai_addr, result->ai_addrlen); if (0 != err) { return 0; } int nSendSize = result->ai_addrlen; sockaddr *remoteAddr = reinterpret_cast<sockaddr *>(new char[nSendSize]); char buffer[1000] = {}; while (true) { int nSendSizeTemp = nSendSize; auto ret = recvfrom(s, buffer, sizeof(buffer), 0, remoteAddr, &nSendSizeTemp); //接收来自客户端的数据 if (0 == ret || SOCKET_ERROR == ret) { break; } ret = sendto(s, buffer, ret, 0, remoteAddr, nSendSizeTemp); //发往客户端 if (0 == ret || SOCKET_ERROR == ret) { break; } char szIp[200] = {}; char szPort[200] = {}; ret = getnameinfo(result->ai_addr, result->ai_addrlen, szIp, sizeof(szIp), szPort, sizeof(szPort), NI_NUMERICSERV | NI_NUMERICHOST); if (0 != ret) { return 0; } std::cout << szIp << ":" << szPort << "," << buffer << std::endl; } delete[] reinterpret_cast<char*>(remoteAddr); closesocket(s); WSACleanup(); return 0; }
客户端代码
#include "stdafx.h" #include <winsock2.h> #include <Ws2tcpip.h> #pragma comment(lib, "ws2_32.lib") #include <iostream> int main() { bool bConnect = true; //使用upd的两种方式 WSADATA wd{}; auto err = WSAStartup(MAKEWORD(2, 2), &wd); if (0 != err) { return 0; } addrinfo *result = nullptr; addrinfo hints = {}; hints.ai_socktype = SOCK_DGRAM; //数据报 hints.ai_protocol = IPPROTO_UDP; //udp hints.ai_family = AF_UNSPEC; //协议无关 auto dwRetval = getaddrinfo("127.0.0.1","3000",&hints,&result); //127.0.0.1 为服务器ip,并且表明是ipv4。3000 为服务器端口号 if (0 != dwRetval) { return 0; } auto s = socket(result->ai_family, result->ai_socktype, result->ai_protocol); if (INVALID_SOCKET == s) { return 0; } char buffer[] = "你好啊呵呵"; char bufferRecv[1024] = {}; //udp两种方式 if (bConnect) //第一种,使用connect { auto ret = connect(s, result->ai_addr, result->ai_addrlen); if (0 != ret) { return 0; } for (int i = 0; i != 10 ; i++) { ret = send(s, buffer, sizeof(buffer), 0); if (SOCKET_ERROR == ret) { return 0; } ret = recv(s, bufferRecv, sizeof(bufferRecv), 0); if (SOCKET_ERROR == ret) { return 0; } char szIp[200] = {}; char szPort[200] = {}; ret = getnameinfo(result->ai_addr, result->ai_addrlen,szIp, sizeof(szIp), szPort, sizeof(szPort), NI_NUMERICSERV | NI_NUMERICHOST); if (0 != ret) { return 0; } std::cout << szIp << ":" << szPort << "," << bufferRecv << std::endl; } } else //第二种,不使用connect { for (int i = 0; i != 10; i++) { auto ret = sendto(s, buffer, sizeof(buffer), 0, result->ai_addr, result->ai_addrlen); if (SOCKET_ERROR == ret) { return 0; } int nSendSize = result->ai_addrlen; sockaddr *remoteAddr2 = reinterpret_cast<sockaddr *>(new char[nSendSize]); ret = recvfrom(s, bufferRecv, sizeof(bufferRecv), 0, remoteAddr2, &nSendSize); if (SOCKET_ERROR == ret) { return 0; } char szIp[200] = {}; char szPort[200] = {}; ret = getnameinfo(remoteAddr2, nSendSize, szIp, sizeof(szIp), szPort, sizeof(szPort), NI_NUMERICSERV | NI_NUMERICHOST); if (0 != ret) { return 0; } std::cout << szIp << ":" << szPort << "," << bufferRecv << std::endl; delete[] reinterpret_cast<char*>(remoteAddr2); } } getchar(); closesocket(s); WSACleanup(); return 0; }
相关文章推荐
- Epoll 的udp通信代码(服务器+客户端)
- java socket 服务器代码 自动接收文件并存储服务器 - 服务器多线程支持和多个客户端同时通信:
- UDP服务器/客户端代码示例
- SSL安全套接字服务器和客户端代码示例
- AJAX示例应用-2(两级菜单的联动)-方式2(服务器以字符串形式执行代码在客户端运行)
- 简单的服务器和客户端程序代码实例
- UDP服务器/客户端
- 简单的无连接的udp服务器和客户端
- SharpStreaming项目开发纪实:构建基于RTSP协议的服务器及客户端应用(三)——客户端的业务代码实现
- Java Web服务之“从WSDL文档中生成客户端支持代码”
- 每秒可产生1亿个序列号的序列生成代码 支持64台服务器同步生成
- 错误代码2104:无法下载Silverlight应用程序。请查看Web服务器设置(支持WPF和Clickonce应用程序的相应设置)
- 服务器控件执行客户端代码
- iPhone客户端与服务器间粘包问题的解决代码
- UDP 阻塞模型下 服务器和客户端的建立过程
- UDP通讯:服务器与客户端
- 安装SQL Server2000时出现下面的提示:Microsoft SQL Server 2000 Enterprise Edition服务器组件在此操作系统上不受支持,只有客户端组件
- tcp和udp多线程的epoll服务器+客户端源代码
- C语言 LINUX 环境下 socket UDP 服务器客户端发送信息
- tcp和udp多线程的epoll服务器+客户端源代码