同一端口监听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;}
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 嘴巴里破了变白怎么办 上嘴唇里面长泡怎么办 嘴皮里面长泡怎么办 嘴巴里经常长泡怎么办 嘴唇上长透明泡怎么办 嘴唇上长很多泡怎么办 嘴巴里长白色泡怎么办 做了漂唇起泡了怎么办 漂唇之后起泡了怎么办 漂唇后起了水泡怎么办 嘴唇起泡,弄破了怎么办 九个月的宝宝上火了怎么办 8岁儿童嘴唇起泡怎么办 宝宝嘴皮上火起泡了怎么办 上嘴唇起泡肿了怎么办 上嘴唇突然肿了怎么办? 醒来上嘴唇肿了怎么办 嘴巴突然肿了怎么办呢 下嘴唇肿起来了怎么办 上嘴唇肿了起泡怎么办 上火下嘴唇肿了怎么办 上火嘴唇都肿了怎么办 嘴唇起泡后肿了怎么办 嘴唇上有白点颗粒状怎么办 嘴唇缺了一块红怎么办 人得钩端螺旋体怎么办 脖子上有鸡皮肤怎么办 不结婚老了以后怎么办 丁克族老了怎么办知乎 2个月宝宝咳嗽怎么办 干活累的手疼怎么办 脸上长白色的癣怎么办 全身起红斑很痒怎么办 宝宝脖子红烂了怎么办 背上长红斑很痒怎么办 身上起风疙瘩很痒怎么办 身上起小包很痒怎么办 浑身起红包很痒怎么办 手太粗糙怎么办小窍门 小腿长疙瘩很痒怎么办 腿过敏起红疙瘩怎么办