Socket客户端重复等待服务器在C++中连接

huangapple go评论91阅读模式
英文:

Socket client repeatedly wait for server in connect c++

问题

我想要问一下,如何让套接字客户端重复等待服务器。例如,如果套接字服务器未运行,那么在connect()期间客户端会等待大约1-3秒,然后抛出错误10038(WSAENOTSOCK)。如果服务器准备好,它会连接。

我希望客户端在服务器无法访问时等待。是否有任何标志可以实现这一点?我尝试将connect()放入while()循环中,但没有用。

以下是重要的代码部分:

  1. #define SOCKET_DEFAULT_PROTOCOL SOCK_STREAM
  2. typedef struct dev_socket {
  3. std::string ip = "";
  4. std::thread openner;
  5. unsigned short port = 0;
  6. SOCKET num = 0, external_num = 0;
  7. } dev_socket;
  8. int openClientSocket(dev_socket &io, std::string server_ipv4, unsigned short port) {
  9. char *server_name = (server_ipv4.empty() ? localhost_addr : const_cast<char*>(server_ipv4.c_str()));
  10. int retval, socket_type = SOCKET_DEFAULT_PROTOCOL;
  11. struct sockaddr_in server;
  12. struct hostent *hp;
  13. #if defined(_WIN32)
  14. int fromlen;
  15. #else
  16. socklen_t fromlen;
  17. #endif
  18. #if defined(_WIN32)
  19. WSADATA wsaData;
  20. if ((retval = WSAStartup(MAKEWORD(2, 0), &wsaData)) != 0) {
  21. cout << "ERROR! Client: WSAStartup() failed (socket number " + std::to_string(io.num) +
  22. ") with error " + std::to_string(retval) + ".\n";
  23. WSACleanup();
  24. return 1;
  25. }
  26. #endif
  27. // 尝试检测是否应该调用gethostbyname()还是gethostbyaddr()
  28. hp = gethostbyname(server_name);
  29. if (hp == NULL) {
  30. cout << "ERROR! Client: Cannot resolve address \"" + (std::string)(server_name) + "\": Error.\n";
  31. cleenup();
  32. return 1;
  33. }
  34. // 创建套接字
  35. // 将解析的信息复制到sockaddr_in结构中
  36. memset(&server, 0, sizeof(server));
  37. memcpy(&(server.sin_addr), hp->h_addr, hp->h_length);
  38. server.sin_family = hp->h_addrtype;
  39. server.sin_port = htons(port);
  40. io.num = socket(AF_INET, socket_type, 0); /* 打开套接字 */
  41. if (io.num < 0) {
  42. cout << "ERROR! Client: Error Opening socket number " + std::to_string(io.num) + ". " + getSocketErrorOrNewLine();
  43. cleenup();
  44. return 1;
  45. }
  46. // 连接
  47. if ((connect(io.num, (struct sockaddr*)&server, sizeof(server))) == -1) {
  48. cout << "ERROR! Client: connect() failed (socket number " + std::to_string(io.num) + "). " + getSocketErrorOrNewLine();
  49. cleenup();
  50. return 1;
  51. }
  52. }

非常感谢您的回答。

英文:

I would like to ask, how to make socket client repeatedly waiting for server. For example if socket server is not running, then client is waiting about 1-3 seconds during connect() and then throw error 10038 (WSAENOTSOCK). If server is ready, then it connects.

I want the client wait if server is unreachable. Is there any flag for this? I tried to put connect() into while() loop but it was not useful.

Here is the important fromcode

  1. #define SOCKET_DEFAULT_PROTOCOL SOCK_STREAM
  2. typedef struct dev_socket {
  3. std::string ip = "";
  4. std::thread openner;
  5. unsigned short port = 0;
  6. SOCKET num = 0, external_num = 0;
  7. }dev_socket;
  8. int openClientSocket(dev_socket &io, std::string server_ipv4, unsigned short port) {
  9. char *server_name = (server_ipv4.empty() ? localhost_addr : const_cast<char*>(server_ipv4.c_str()));
  10. int retval, socket_type = SOCKET_DEFAULT_PROTOCOL;
  11. struct sockaddr_in server;
  12. struct hostent *hp;
  13. #if defined(_WIN32)
  14. int fromlen;
  15. #else
  16. socklen_t fromlen;
  17. #endif
  18. #if defined(_WIN32)
  19. WSADATA wsaData;
  20. if ((retval = WSAStartup(MAKEWORD(2, 0), &wsaData)) != 0) {
  21. cout << "ERROR! Client: WSAStartup() failed (socket number " + std::to_string(io.num) +
  22. ") with error " + std::to_string(retval) + ".\n";
  23. WSACleanup();
  24. return 1;
  25. }
  26. #endif
  27. // Attempt to detect if we should call gethostbyname() or gethostbyaddr()
  28. hp = gethostbyname(server_name);
  29. if (hp == NULL) {
  30. cout << "ERROR! Client: Cannot resolve address \"" + (std::string)(server_name) + "\": Error.\n";
  31. cleenup();
  32. return 1;
  33. }
  34. //Creating SOCKET
  35. // Copy the resolved information into the sockaddr_in structure
  36. memset(&server, 0, sizeof(server));
  37. memcpy(&(server.sin_addr), hp->h_addr, hp->h_length);
  38. server.sin_family = hp->h_addrtype;
  39. server.sin_port = htons(port);
  40. io.num = socket(AF_INET, socket_type, 0); /* Open a socket */
  41. if (io.num < 0) {
  42. cout << "ERROR! Client: Error Opening socket number " + std::to_string(io.num) + ". " + getSocketErrorOrNewLine();
  43. cleenup();
  44. return 1;
  45. }
  46. //CONNECTing
  47. if ((connect(io.num, (struct sockaddr*)&server, sizeof(server))) == -1) {
  48. cout << "ERROR! Client: connect() failed (socket number " + std::to_string(io.num) + "). " + getSocketErrorOrNewLine();
  49. cleenup();
  50. return 1;
  51. }
  52. }

Thank you in advance for your answers.

UPDATE: The while() loop is working (but probably not best) solution - there was bug in testing api.

答案1

得分: 0

"很多人都写过,while循环是唯一的方法。我希望有一种“漂亮”的解决方案,但这也可以。"

英文:

As many of you wrote, the while cycle is the only way. I hoped that there is some "pretty" solution, but this is also fine.

huangapple
  • 本文由 发表于 2023年3月15日 17:59:02
  • 转载请务必保留本文链接:https://go.coder-hub.com/75743119.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定