当前位置:   article > 正文

devc++ 使用 winsock 实现 UDP 广播

devc++ 使用 winsock 实现 UDP 广播

参考链接

使用UDP发送广播报_udp广播 inaddr_broadcast-CSDN博客

UDP接收端收不到广播的消息问题排查_unity upd广播连接不上是什么情况-CSDN博客

 如何禁用自己电脑的虚拟网卡-百度经验 (baidu.com)

但是wifi 会屏蔽255.255.255.255 广播地址,所以 255.255.255.255 需要借助手机 wifi 路由实现真正局域网内广播,两台电脑连上同一个手机热点后,就可以发消息了。

一般的局域网游戏需要 UDP 广播,然后获取到 IP 才能定向发送消息。

而广播 UDP 的方法和 UDP 定向发送的 方法有些出入,这里是 移植到 DEVC++ 的 UDP 局域网广播方法。

参考第二条连接,在两台电脑连上同一个手机热点后,如果 UDP 还收不到消息:

同一个交换机下 是可以收到广播的 还有就是
电脑的虚拟网卡会拦截广播操作,因为你没有指定一个地址,所以代码正确的情况下,发送不出去或者接收不到,只需要考虑以下两种情况。
1.广播端虚拟网卡没有禁用
2.接收端虚拟网卡没有禁用

PS.虚拟网卡一般是装了虚拟机才会有的。

服务端

  1. // 服务器端
  2. // Server.cpp : Defines the entry point for the console application.
  3. //
  4. #include <WinSock2.h>
  5. #include <stdio.h>
  6. #pragma comment(lib, "ws2_32.lib")
  7. #pragma warning(disable : 4996)
  8. const int MAX_BUF_LEN = 255;
  9. int main(int argc, CHAR* argv[])
  10. {
  11. WORD wVersionRequested;
  12. WSADATA wsaData;
  13. int err;
  14. // 启动socket api
  15. wVersionRequested = MAKEWORD( 2, 2 );
  16. err = WSAStartup( wVersionRequested, &wsaData );
  17. if ( err != 0 )
  18. {
  19. return -1;
  20. }
  21. if ( LOBYTE( wsaData.wVersion ) != 2 ||
  22. HIBYTE( wsaData.wVersion ) != 2 )
  23. {
  24. WSACleanup( );
  25. return -1;
  26. }
  27. // 创建socket
  28. SOCKET connect_socket;
  29. connect_socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
  30. if(INVALID_SOCKET == connect_socket)
  31. {
  32. err = WSAGetLastError();
  33. printf("/""socket/"" error! error code is %d/n", err);
  34. return -1;
  35. }
  36. SOCKADDR_IN sin;
  37. sin.sin_family = AF_INET;
  38. sin.sin_port = htons(3779);
  39. sin.sin_addr.s_addr = INADDR_BROADCAST; // 255.255.255.255 但是会被路由器屏蔽,不过借用手机热点可以广播,只要两个电脑连同一个手机热点就能广播
  40. bool bOpt = true;
  41. //设置该套接字为广播类型
  42. setsockopt(connect_socket, SOL_SOCKET, SO_BROADCAST, (char*)&bOpt, sizeof(bOpt));
  43. int nAddrLen = sizeof(SOCKADDR);
  44. char buff[MAX_BUF_LEN] = "";
  45. int nLoop = 0;
  46. while(1)
  47. {
  48. nLoop++;
  49. sprintf(buff, "%8d", nLoop);
  50. // 发送数据
  51. int nSendSize = sendto(connect_socket, buff, strlen(buff), 0, (SOCKADDR*)&sin, nAddrLen);
  52. if(SOCKET_ERROR == nSendSize)
  53. {
  54. err = WSAGetLastError();
  55. printf("/""sendto/"" error!, error code is %d/n", err);
  56. return -1;
  57. }
  58. printf("Send: %s/n", buff);
  59. Sleep(500);
  60. }
  61. return 0;
  62. }

客户端

  1. // 客户端
  2. // Client.cpp : Defines the entry point for the console application.
  3. //
  4. #include <WinSock2.h>
  5. #include <stdio.h>
  6. #pragma comment(lib, "ws2_32.lib")
  7. #pragma warning(disable : 4996)
  8. const int MAX_BUF_LEN = 255;
  9. int main(int argc, CHAR* argv[])
  10. {
  11. WORD wVersionRequested;
  12. WSADATA wsaData;
  13. int err;
  14. // 启动socket api
  15. wVersionRequested = MAKEWORD( 2, 2 );
  16. err = WSAStartup( wVersionRequested, &wsaData );
  17. if ( err != 0 )
  18. {
  19. return -1;
  20. }
  21. if ( LOBYTE( wsaData.wVersion ) != 2 || HIBYTE( wsaData.wVersion ) != 2 )
  22. {
  23. WSACleanup( );
  24. return -1;
  25. }
  26. // 创建socket
  27. SOCKET connect_socket;
  28. connect_socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
  29. if(INVALID_SOCKET == connect_socket)
  30. {
  31. err = WSAGetLastError();
  32. printf("/""socket/"" error! error code is %d/n", err);
  33. return -1;
  34. }
  35. // 用来绑定套接字
  36. SOCKADDR_IN sin;
  37. sin.sin_family = AF_INET;
  38. sin.sin_port = htons(3779);
  39. sin.sin_addr.s_addr = 0;
  40. // 用来从网络上的广播地址接收数据
  41. SOCKADDR_IN sin_from;
  42. sin_from.sin_family = AF_INET;
  43. sin_from.sin_port = htons(3779); // 端口和服务端一致
  44. sin_from.sin_addr.s_addr = INADDR_ANY; // 接收全部广播
  45. //设置该套接字为广播类型,
  46. bool bOpt = true;
  47. setsockopt(connect_socket, SOL_SOCKET, SO_BROADCAST, (char*)&bOpt, sizeof(bOpt));
  48. // 绑定套接字
  49. err = bind(connect_socket, (SOCKADDR*)&sin, sizeof(SOCKADDR));
  50. if(SOCKET_ERROR == err)
  51. {
  52. err = WSAGetLastError();
  53. printf("/""bind/"" error! error code is %d/n", err);
  54. return -1;
  55. }
  56. int nAddrLen = sizeof(SOCKADDR);
  57. char buff[MAX_BUF_LEN] = "";
  58. while(1)
  59. {
  60. // 接收数据
  61. int nSendSize = recvfrom(connect_socket, buff, MAX_BUF_LEN, 0, (SOCKADDR*)&sin_from, &nAddrLen);
  62. if(SOCKET_ERROR == nSendSize)
  63. {
  64. err = WSAGetLastError();
  65. printf("/""recvfrom/"" error! error code is %d/n", err);
  66. return -1;
  67. }
  68. buff[nSendSize] = '/0';
  69. printf("Recv: %s/n", buff);
  70. }
  71. return 0;
  72. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/从前慢现在也慢/article/detail/112394
推荐阅读
相关标签
  

闽ICP备14008679号