You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

tcpsocket.cpp 2.2 kB

8 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. #include "tcpsocket.h"
  2. #include <sys/socket.h>
  3. #include <arpa/inet.h>
  4. #include <stdio.h>
  5. #include <sys/time.h>
  6. #include <errno.h>
  7. #include <unistd.h>
  8. TcpSocket::TcpSocket()
  9. {
  10. }
  11. TcpSocket::TcpSocket(int socket)
  12. {
  13. mSocket = socket;
  14. if (mSocket != -1)
  15. {
  16. sockaddr_in addr;
  17. socklen_t len = sizeof(addr);
  18. auto ret = getpeername(mSocket, (sockaddr*)&addr, &len);
  19. if (ret == 0)
  20. {
  21. mPeerIp = inet_ntoa(addr.sin_addr);
  22. }
  23. }
  24. }
  25. TcpSocket::~TcpSocket()
  26. {
  27. disconnect();
  28. }
  29. bool TcpSocket::connect(const string &ip, int port)
  30. {
  31. if (mSocket != -1)
  32. return true;
  33. mSocket = socket(AF_INET, SOCK_STREAM, 0);
  34. if (mSocket == -1)
  35. {
  36. perror("faield to create socket");
  37. return false;
  38. }
  39. sockaddr_in addr;
  40. addr.sin_addr.s_addr = inet_addr(ip.c_str());
  41. addr.sin_family = AF_INET;
  42. addr.sin_port = htons(port);
  43. int ret = ::connect(mSocket, (sockaddr*)&addr, sizeof(addr));
  44. if (ret == -1)
  45. {
  46. perror("failed to connect");
  47. close(mSocket);
  48. return false;
  49. }
  50. mPeerIp = ip;
  51. return true;
  52. }
  53. void TcpSocket::disconnect()
  54. {
  55. if (mSocket != -1)
  56. {
  57. close(mSocket);
  58. mPeerIp="";
  59. }
  60. }
  61. int TcpSocket::send(const void *data, int size)
  62. {
  63. int sent = 0;
  64. auto pdata = static_cast<const char*>(data);
  65. while (sent < size)
  66. {
  67. int ret = ::send(mSocket, pdata+sent, size-sent, 0);
  68. if (ret == -1 )
  69. {
  70. if (errno != EAGAIN)
  71. {
  72. perror("tcp send failed");
  73. return -1;
  74. }
  75. continue;
  76. }
  77. sent+=ret;
  78. }
  79. return sent;
  80. }
  81. int TcpSocket::recv(void *data, int size, int msTimeout)
  82. {
  83. timeval tv = {msTimeout/1000, (msTimeout%1000)*1000};
  84. setsockopt(mSocket, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
  85. int ret = ::recv(mSocket, data, size, 0);
  86. if (ret == -1)
  87. {
  88. if (errno == ETIMEDOUT || errno == EAGAIN)
  89. return -1;
  90. else
  91. {
  92. perror("recv failed");
  93. return -2;
  94. }
  95. }
  96. return ret;
  97. }

mac下的“飞秋”大多数只是飞鸽传书协议,而且未发现令人满意的开源项目,所以基于c++与qt实现了基础的飞秋协议。

Contributors (1)