同一端口监听TCP与UDP数据包
来源:互联网 发布:微商怎么利用淘宝引流 编辑:程序博客网 时间:2024/05/16 10:41
代码示例展示了关于udp与tcp在同一端口下的监听实现,具体的阻塞问题在网络模型里面有实现,可以查阅我提到的网络模型。这里主要是解决大家对端口绑定的疑惑。
#define _WINSOCK_DEPRECATED_NO_WARNINGS#include <stdio.h>#include<winsock2.h>#include<windows.h>#include <list>#pragma comment(lib,"Ws2_32.lib")using namespace std;#define MAX_RECV 1024enum _PORT{ PORT = 6000 // server port};typedef struct //存储tcp连接的客户端的信息{ SOCKET *sock; SOCKADDR_IN addr;}USER;list<USER*> user_list;list<USER*>::iterator iter;SOCKET tcpSock;SOCKET udpSock;SOCKADDR_IN addrServ;bool InitNet();// init networkbool InitTcpServer();// init tcp serverbool InitUdpServer();// init udp serverbool BeginTcpAccept();// TCP begin acceptvoid Clean();// cleanDWORD WINAPI UdpServerRecvProc(LPVOID lparam); // udp server recvfrom threadDWORD WINAPI TcpServerRecvProc(LPVOID lparam); // tcp server recv threadint main(){ if (!InitNet()) return -1; if (!InitTcpServer()) return -1; if (!InitUdpServer()) return -1; CreateThread(NULL, NULL, TcpServerRecvProc, NULL, NULL, NULL); CreateThread(NULL, NULL, UdpServerRecvProc, (LPVOID)&udpSock, NULL, NULL); BeginTcpAccept(); Clean(); return 0;}bool InitNet(){ WSAData wsa; if (WSAStartup(MAKEWORD(2, 2), &wsa) != 0) { printf("WSAStartup error:%d", WSAGetLastError()); WSACleanup(); return false; } return true;}bool InitTcpServer(){ tcpSock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (INVALID_SOCKET == tcpSock) { printf("tcpSock init error:%d", WSAGetLastError()); WSACleanup(); closesocket(tcpSock); return false; } addrServ.sin_family = AF_INET; addrServ.sin_port = htons(PORT); addrServ.sin_addr.S_un.S_addr = htonl(ADDR_ANY); int ret = bind(tcpSock, (sockaddr*)&addrServ, sizeof(addrServ)); if (SOCKET_ERROR == ret) { printf("tcpSock bind error:%d", WSAGetLastError()); WSACleanup(); closesocket(tcpSock); return false; } ret = listen(tcpSock, SOMAXCONN); if (SOCKET_ERROR == ret) { printf("tcpSock listen error:%d", WSAGetLastError()); WSACleanup(); closesocket(tcpSock); return false; } return true;}bool InitUdpServer(){ udpSock = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP); if (INVALID_SOCKET == udpSock) { printf("udpSock init error:%d\n", WSAGetLastError()); WSACleanup(); closesocket(udpSock); return false; } int ret = bind(udpSock, (sockaddr*)&addrServ, sizeof(addrServ)); if (SOCKET_ERROR == ret) { printf("udp bind error:%d\n", WSAGetLastError()); WSACleanup(); closesocket(udpSock); return false; } return true;}bool BeginTcpAccept(){ SOCKADDR_IN addrClient = { 0 }; int len = sizeof(SOCKADDR_IN); while (TRUE) { SOCKET *sockClient = new SOCKET; *sockClient = accept(tcpSock, (sockaddr*)&addrClient, &len); if (INVALID_SOCKET == *sockClient) { printf("accpet() error:%d", WSAGetLastError()); WSACleanup(); closesocket(tcpSock); return false; } printf("TCP_MSG [%s:%d]->log on\n", inet_ntoa(addrClient.sin_addr), htons(addrClient.sin_port)); USER *user = new USER; user->sock = sockClient; user->addr = addrClient; user_list.push_back(user); } return true;}void Clean(){ WSACleanup(); closesocket(tcpSock); closesocket(udpSock);}DWORD WINAPI UdpServerRecvProc(LPVOID lparam){ char buf[MAX_RECV]; SOCKET* udpSer = (SOCKET*)lparam; SOCKADDR_IN udpSrcAddr; ZeroMemory(&udpSrcAddr, sizeof(udpSrcAddr)); int nLen = sizeof(udpSrcAddr); while (true) { memset(buf, '\0', MAX_RECV); int iRet = recvfrom(*udpSer, buf, MAX_RECV, 0, (sockaddr*)&udpSrcAddr, &nLen); if (SOCKET_ERROR == iRet) { printf("recvfrom() error + %d", GetLastError()); continue; } printf("UDP_MSG [%s:%d]:%s\n", inet_ntoa(udpSrcAddr.sin_addr), htons(udpSrcAddr.sin_port), buf); } return 0;}DWORD WINAPI TcpServerRecvProc(LPVOID lparam){ int addr_len = sizeof(SOCKADDR_IN); char recvBuf[MAX_RECV]; while (true) { if (user_list.size() == 0) { Sleep(30); continue; } for (iter = user_list.begin(); iter != user_list.end(); ++iter) { memset(recvBuf, 0, MAX_RECV); // 此处的阻塞问题,导致只能 依次 接收链表中套接字发来的数据 // 解决recv阻塞的问题,请阅读我关于 网络模型 的博文 int ret = recv(*((*iter)->sock), recvBuf, MAX_RECV, 0); if (0 == ret) { printf("TCP_MSG [%s:%d]->log off\n", inet_ntoa((*iter)->addr.sin_addr), htons((*iter)->addr.sin_port)); closesocket(*(*iter)->sock); iter = user_list.erase(iter); // 从链表中删除 if (user_list.size() == 0) break; continue; } if (SOCKET_ERROR == ret) { printf("recv() error + %d", WSAGetLastError()); WSACleanup(); closesocket(*(*iter)->sock); return -1; } printf("TCP_MSG [%s:%d]:%s\n", inet_ntoa((*iter)->addr.sin_addr), htons((*iter)->addr.sin_port), recvBuf); } } return 0;}
阅读全文
1 0
- 同一端口监听TCP与UDP数据包
- 同一端口监听tcp和udp请求
- TCP与UDP数据包结构
- TCP 和UDP绑定同一端口
- tcp与udp数据包的大小
- Android UDP 监听数据包
- TCP、UDP绑定同一端口通信的解释
- 【转】TCP 和 UDP 绑定同一端口通信的解释
- TCP、UDP绑定同一端口通信的解释
- TCP、UDP绑定同一端口通信的解释
- TCP、UDP绑定同一端口通信的解释
- TCP 和 UDP 绑定同一端口通信的解释
- TCP、UDP绑定同一端口通信的解释-转
- TCP、UDP绑定同一端口通信的解释
- TCP和UDP是否可以绑定同一端口进行通信
- TCP、UDP绑定同一端口通信的解释
- tcp udp 数据包大小
- TCP、UDP数据包传输
- solr配置中文IK Analyzer分词器
- WordPress 安装在mac上步骤
- 开门大吉。
- java作业
- Serverless 应用开发指南:serverless 的 hello, world
- 同一端口监听TCP与UDP数据包
- 建造者模式
- 使用NGUI里Localization文件注意事项
- 如何只搜索自己博客站的文章
- SpringMVC @RequestBody问题:Unrecognized field , not marked as ignorable
- Spring设计模式之JDK的动态代理!
- 手机网络连接类型判断 2/3/4G网络 WiFi和无网络 工具类
- Android universal-Image-Loader原理详解
- LINUX中常用操作命令