标签:线程 startup link 告诉 sig code 地址 学习笔记 ddr
C++学习笔记,UDP(socket)协议的封装实现
1.配置QT下的pro文件
1 TEMPLATE = app 2 CONFIG += console 3 CONFIG -= app_bundle 4 CONFIG -= qt 5 6 LIBS += -lWs2_32 ##标示使用window下的Ws2_32.lib,-l表示要链接后面的库 7 #-lWs2_32,link Ws2_32.lib 8 9 SOURCES += main.cpp 10 udp.cpp 11 12 include(deployment.pri) 13 qtcAddDeployment() 14 15 16 HEADERS += 17 udp.h
2.编写udp.h文件
1 #ifndef UDP_H 2 #define UDP_H 3 4 #ifdef MYLINUX 5 6 #include <unistd.h> 7 #include <arpa/inet.h> 8 #include <sys/types.h> /* See NOTES */ 9 #include <sys/socket.h> 10 11 #define SOCKET int 12 13 #else 14 #include <winsock2.h> 15 #endif 16 17 class myudp 18 { 19 private: 20 SOCKET st;//类的内部成员一般是不暴露在外面的 21 public: 22 myudp(); 23 ~myudp(); 24 25 int socket_send(const char * IP,const char *buf, int len); 26 int socket_recv(char *buf, int len, char * srcIP); 27 int socket_bind(short int port); 28 }; 29 30 #endif // UDP_H
3.编写udp.cpp
1 #include <string.h> 2 #include <stdio.h> 3 #include "udp.h" 4 5 //#define MYLINUX ---- linux 下 makefile文件定义 -DMYLINUX 6 7 8 9 10 11 int myudp::socket_send(const char * IP,const char *buf, int len) 12 { 13 14 st = socket(AF_INET, SOCK_DGRAM, 0); 15 //建立一个socket,第一个参数是指定socket要用哪个协议,AF_INET代表要用TCP/IP协议 16 //第二个参数SOCK_DGRAM意思是要用UDP协议 17 //第三个参数一般默认填0 18 struct sockaddr_in addr; 19 memset(&addr, 0, sizeof(addr));//初始化结构addr 20 addr.sin_family = AF_INET;//代表要使用一个TCP/IP的地址 21 addr.sin_port = htons(8080);//host to net short 22 addr.sin_addr.s_addr = inet_addr(IP); 23 //IP地址解析 24 //unsigned long laddr = inet_addr("192.168.6.200"); 25 //unsigned char *p = &laddr; 26 //printf("%u, %u, %u, %u\n", *(p), *(p+1), *(p+2), *(p+3)); 27 28 size_t rc = 0; 29 30 //发送udp数据 31 rc = sendto(st,buf,len,0,(struct sockaddr *)&addr,sizeof(addr)); 32 33 return rc; 34 } 35 36 int myudp::socket_recv(char *buf, int len, char * srcIP) 37 { 38 struct sockaddr_in sendaddr;//来自发送方的IP地址 39 memset(&sendaddr,0,sizeof(sendaddr)); 40 41 #ifdef MYLINUX 42 socklen_t len; 43 #else 44 int addrlen; 45 #endif 46 addrlen = sizeof(sendaddr); 47 48 49 memset(buf,0,len); 50 size_t rc = recvfrom(st,buf,len,0,(struct sockaddr *)&sendaddr,&addrlen); 51 //inet_ntoa(sendaddr.sin_addr);//这个函数是不可重入函数 52 //多线程调用,这个函数会出问题 53 if(srcIP) 54 strcpy(srcIP,inet_ntoa(sendaddr.sin_addr)); 55 //printf("%s:\n%s\n", srcIP, buf); 56 return rc; 57 } 58 59 myudp::myudp() 60 { 61 #ifndef MYLINUX 62 //初始化socket 63 DWORD ver; 64 WSADATA wsaData; 65 ver = MAKEWORD(1,1);//在调用WASStartup要告诉windows,我用什么版本的socket 66 WSAStartup(ver, &wsaData);//windows要求,只要用socket,第一步,必须调用这个函数 67 //初始化完成 68 #endif 69 70 st = socket(AF_INET,SOCK_DGRAM,0);//定义一个socket 71 72 } 73 74 75 myudp::~myudp() 76 { 77 #ifdef MYLINUX 78 close(st); 79 #else 80 closesocket(st);//关闭socket 81 WSACleanup();//释放win socket内部的相关资源 82 #endif 83 } 84 85 86 int myudp::socket_bind(short port) 87 { 88 struct sockaddr_in addr; 89 memset(&addr,0,sizeof(addr));//初始化addr 90 addr.sin_family = AF_INET;//代表要使用一个TCP/IP的地址 91 addr.sin_port = htons(port); 92 addr.sin_addr.s_addr = htonl(INADDR_ANY);//作为接收方,不需要指定具体的IP地址,接受的主机是什么IP,我就在什么IP接受数据 93 //addr.sin_addr.s_addr = inet_addr("192.168.2.100"); 94 95 return bind(st, (struct sockaddr *)&addr, sizeof(addr)); //将端口号和程序绑定 96 }
4.main.c的实现代码
1 #include <iostream> 2 #include "udp.h" 3 4 using namespace std; 5 6 int main(int argc, char *args[]) 7 { 8 if(argc > 1) 9 { 10 myudp udp; 11 char buf[1024] = {0}; 12 while(1) 13 { 14 memset(buf, 0, sizeof(buf)); 15 gets(buf); 16 udp.socket_send(args[1],buf, strlen(buf)); 17 if (strcmp(buf, "exit") == 0) 18 break; 19 } 20 21 }else 22 { 23 myudp udp; 24 char buf[1024] = {0}; 25 if(udp.socket_bind(8080) > -1) 26 { 27 char ip[100] = {0}; 28 while(1) 29 { 30 memset(buf, 0, sizeof(buf)); 31 memset(ip, 0, sizeof(ip)); 32 udp.socket_recv(buf,sizeof(buf), ip); 33 if (strncmp(buf, "exit", 4) == 0) 34 break; 35 cout << ip << endl; 36 cout << buf << endl; 37 } 38 } 39 } 40 41 cout << "over" << endl; 42 return 0; 43 }
标签:线程 startup link 告诉 sig code 地址 学习笔记 ddr
原文地址:https://www.cnblogs.com/rainbow-xiaojian/p/9061257.html