如何在c中接收winsock的udp数据包?

前端之家收集整理的这篇文章主要介绍了如何在c中接收winsock的udp数据包?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
作为一个包围我的头围绕udp套接字的尝试,我试图将代码从本教程页面 http://www.linuxhowtos.org/C_C++/socket.htm移植到winsock(运行在win 8,如果重要). [下面的直接链接]

代码当前编译并运行,但是我从来没有收到数据包,这两个程序只是等待并阻止recvfrom().我不断有这个同样的问题(例如,使用这个代码https://stackoverflow.com/a/679529/873217修改版本,包括一个recvfrom()调用,并用这个代码C++ problem with Datagram (UDP)winsocket to sendto and recvfrom on the same socket through the loopback adapter进行更改).我想我正在做一些简单和根本的错误;但我无法自己找到它.希望有更多经验的人可以为我解决这个问题.谢谢.

补充笔记:
我正在运行服务器exe然后客户端exe在同一台计算机上.它被连接到互联网.我也尝试使用一个解析到我的IP地址的域名.我也尝试禁用防火墙,尽管我允许这两个程序完全访问.

直接链接到原始客户端和服务器代码
http://www.linuxhowtos.org/data/6/client_udp.c
http://www.linuxhowtos.org/data/6/server_udp.c

我目前的尝试:

两者都链接到libws2_32.a

客户端代码

  1. #include <stdio.h>
  2. #include <winsock2.h>
  3. #include <string.h>
  4.  
  5. void error(const char *);
  6.  
  7. int main()
  8. {
  9. WSAData data;
  10. WSAStartup( MAKEWORD( 2,2 ),&data );
  11.  
  12. int sock,n;
  13. int length;
  14. struct sockaddr_in server,from;
  15. struct hostent *hp;
  16. char buffer[256];
  17. unsigned short serverPort = 27072;
  18. sock = socket(AF_INET,SOCK_DGRAM,0);
  19. if (sock < 0) error("socket");
  20. server.sin_family = AF_INET;
  21. hp = gethostbyname("localhost");//have also tried my url
  22. if (hp==0) error("Unknown host");
  23. memmove((char *)hp->h_addr,(char *)&server.sin_addr,hp->h_length);
  24. server.sin_port = htons(serverPort);
  25. length = sizeof(struct sockaddr_in);
  26. printf("Please enter the message: ");
  27. memset(buffer,256);
  28. fgets(buffer,255,stdin);
  29. n = sendto (sock,buffer,strlen(buffer),(const struct sockaddr *)&server,length);
  30. if (n < 0) error("Sendto");
  31. printf("sent %i bytes\n",n);
  32. n = recvfrom(sock,256,(struct sockaddr *)&server,&length);
  33. if (n < 0) error("recvfrom");
  34. //write(1,"Got an ack: ",12);
  35. //write(1,n);
  36. printf("Got msg: %s\n",buffer);
  37.  
  38. closesocket(sock);
  39. WSACleanup();
  40. return(0);
  41. }
  42.  
  43. void error(const char *msg)
  44. {
  45. perror(msg);
  46. exit(0);
  47. }

服务器代码

  1. #include <stdio.h>
  2. #include <winsock2.h>
  3. #include <string.h>
  4.  
  5. void error(const char *);
  6.  
  7. int main()
  8. {
  9. WSAData data;
  10. WSAStartup( MAKEWORD( 2,length,n;
  11. int fromlen;
  12. struct sockaddr_in server;
  13. struct sockaddr_in from;
  14. char buf[1024];
  15. unsigned short serverPort = 27072;
  16. sock=socket(AF_INET,0);
  17. if (sock < 0) error("opening socket");
  18. length = sizeof(server);
  19. memset(&server,length);
  20. server.sin_family = AF_INET;
  21. server.sin_addr.s_addr=INADDR_ANY;
  22. server.sin_port=htons(serverPort);
  23. if (bind(sock,length)<0) error ("binding");
  24. fromlen = sizeof(struct sockaddr_in);
  25. while(1)
  26. {
  27. n = recvfrom(sock,buf,1024,(struct sockaddr *)&from,&fromlen);
  28. if (n<0) error("recvfrom");
  29. //write(1,"Received a datagram: ",21);
  30. //write(1,n);
  31. printf("Received a datagram: %s",buf);
  32. n = sendto(sock,"Got your message\n",17,fromlen);
  33. if (n<0)error("sendto");
  34. }
  35. closesocket(sock);
  36. WSACleanup();
  37. return 0;
  38. }
  39.  
  40.  
  41. void error (const char *msg)
  42. {
  43. perror(msg);
  44. exit(0);
  45. }

解决方法

以下UDP测试应用程序在我的设置 – Windows 7,VS 2013上正常工作.

我创建了一些轻量级的包装类来进行资源管理,并将错误代码转换为异常.这使得客户端和服务器代码更容易阅读.请务必先运行服务器.

Network.h

  1. #include <WinSock2.h>
  2. #include <WS2tcpip.h>
  3. #include <system_error>
  4. #include <string>
  5. #include <iostream>
  6.  
  7. #pragma once
  8.  
  9. class WSASession
  10. {
  11. public:
  12. WSASession()
  13. {
  14. int ret = WSAStartup(MAKEWORD(2,2),&data);
  15. if (ret != 0)
  16. throw std::system_error(WSAGetLastError(),std::system_category(),"WSAStartup Failed");
  17. }
  18. ~WSASession()
  19. {
  20. WSACleanup();
  21. }
  22. private:
  23. WSAData data;
  24. };
  25.  
  26. class UDPSocket
  27. {
  28. public:
  29. UDPSocket()
  30. {
  31. sock = socket(AF_INET,IPPROTO_UDP);
  32. if (sock == INVALID_SOCKET)
  33. throw std::system_error(WSAGetLastError(),"Error opening socket");
  34. }
  35. ~UDPSocket()
  36. {
  37. closesocket(sock);
  38. }
  39.  
  40. void SendTo(const std::string& address,unsigned short port,const char* buffer,int len,int flags = 0)
  41. {
  42. sockaddr_in add;
  43. add.sin_family = AF_INET;
  44. add.sin_addr.s_addr = inet_addr(address.c_str());
  45. add.sin_port = htons(port);
  46. int ret = sendto(sock,len,flags,reinterpret_cast<SOCKADDR *>(&add),sizeof(add));
  47. if (ret < 0)
  48. throw std::system_error(WSAGetLastError(),"sendto Failed");
  49. }
  50. void SendTo(sockaddr_in& address,int flags = 0)
  51. {
  52. int ret = sendto(sock,reinterpret_cast<SOCKADDR *>(&address),sizeof(address));
  53. if (ret < 0)
  54. throw std::system_error(WSAGetLastError(),"sendto Failed");
  55. }
  56. sockaddr_in RecvFrom(char* buffer,int flags = 0)
  57. {
  58. sockaddr_in from;
  59. int size = sizeof(from);
  60. int ret = recvfrom(sock,reinterpret_cast<SOCKADDR *>(&from),&size);
  61. if (ret < 0)
  62. throw std::system_error(WSAGetLastError(),"recvfrom Failed");
  63.  
  64. // make the buffer zero terminated
  65. buffer[ret] = 0;
  66. return from;
  67. }
  68. void Bind(unsigned short port)
  69. {
  70. sockaddr_in add;
  71. add.sin_family = AF_INET;
  72. add.sin_addr.s_addr = htonl(INADDR_ANY);
  73. add.sin_port = htons(port);
  74.  
  75. int ret = bind(sock,"Bind Failed");
  76. }
  77.  
  78. private:
  79. SOCKET sock;
  80. };

服务器

  1. #include "Network.h"
  2.  
  3. int main()
  4. {
  5. try
  6. {
  7. WSASession Session;
  8. UDPSocket Socket;
  9. char buffer[100];
  10.  
  11. Socket.Bind(100);
  12. while (1)
  13. {
  14. sockaddr_in add = Socket.RecvFrom(buffer,sizeof(buffer));
  15.  
  16. std::string input(buffer);
  17. std::reverse(std::begin(input),std::end(input));
  18. Socket.SendTo(add,input.c_str(),input.size());
  19. }
  20. }
  21. catch (std::system_error& e)
  22. {
  23. std::cout << e.what();
  24. }
  25. }

客户

  1. #include "Network.h"
  2.  
  3. int main()
  4. {
  5. try
  6. {
  7. WSASession Session;
  8. UDPSocket Socket;
  9. std::string data = "hello world";
  10. char buffer[100];
  11.  
  12. Socket.SendTo("127.0.0.1",100,data.c_str(),data.size());
  13. Socket.RecvFrom(buffer,100);
  14. std::cout << buffer;
  15. }
  16. catch (std::exception &ex)
  17. {
  18. std::cout << ex.what();
  19. }
  20. char c;
  21. std::cin >> c;
  22. }

猜你在找的C&C++相关文章