程序是基于TCP的,只是为了测试,功能并不完善。
大多数的心跳都是UDP协议。当服务器端的数据和心跳在同一端口时,TCP协议很容易出现心跳被阻塞的情况。
服务器端代码:
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 #include <unistd.h> 2 #include <arpa/inet.h> 3 #include <netinet/in.h> 4 #include <sys/socket.h> 5 #include <iostream> 6 #include <string.h> 7 #include <cstdlib> 8 #include <string> 9 using namespace std; 10 11 const short SERVER_PORT = 9527; 12 const int MAX_CONN_NUM = 5; 13 const string SERVER_IP = "192.168.1.105"; 14 const int MAX_DATA_LENGTH = 255; 15 const int MSG_SHAKE_LENGTH = 20; 16 17 struct ShakeHands 18 { 19 int iConnID; 20 int iLength; //通信双方约定,iLength为20即为握手消息 21 int iSendID; 22 int iReceiveID; 23 char extend[4]; 24 25 void SwapID() 26 { 27 int tmp; 28 tmp = iSendID; 29 iSendID = iReceiveID; 30 iReceiveID = tmp; 31 } 32 }; 33 34 int SendMsg(char* msg, int length, int sockfd) 35 { 36 write(sockfd, msg, length); 37 return 0; 38 } 39 40 int ShakeHandsProc(char* msg, int length, int sockfd) 41 { 42 cout << "start proc shake hands" << std::endl; 43 if (NULL == msg || length < 0) 44 { 45 cerr << __LINE__ << __FUNCTION__ << "proc failed"; 46 return -1; 47 } 48 ShakeHands* m_ShakeHands = (struct ShakeHands*)msg; 49 m_ShakeHands->SwapID(); 50 51 if (-1 == SendMsg((char*)m_ShakeHands, length, sockfd)) 52 { 53 return -1; 54 } 55 cout << "end proc shake hands" << std::endl; 56 return 0; 57 } 58 int main(int argc, char** argv) 59 { 60 struct sockaddr_in server_addr, client_addr; 61 int server_len = 0; 62 int client_len = 0; 63 int server_fd = -1; 64 int client_fd = -1; 65 int result = -1; 66 char msg[MAX_DATA_LENGTH] = {0}; 67 int enable = 1; 68 69 server_addr.sin_family = AF_INET; 70 server_addr.sin_addr.s_addr = inet_addr(SERVER_IP.c_str()); 71 server_addr.sin_port = htons(SERVER_PORT); 72 73 server_fd = socket(AF_INET, SOCK_STREAM, 0); 74 setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(int)); 75 if (-1 == bind(server_fd, (sockaddr*)&server_addr, sizeof(server_addr))) 76 { 77 cerr << "bind failed!"; 78 exit(EXIT_FAILURE); 79 } 80 if (-1 == listen(server_fd, MAX_CONN_NUM)) 81 { 82 cerr << "Listen failed!"; 83 exit(EXIT_FAILURE); 84 } 85 86 while(1) 87 { 88 client_fd = accept(server_fd, (struct sockaddr*)&client_addr, (socklen_t*)&client_len); 89 read(client_fd, msg, MAX_DATA_LENGTH); 90 ShakeHands* pShakeHands = (ShakeHands*)msg; 91 if (MSG_SHAKE_LENGTH == pShakeHands->iLength) 92 { 93 ShakeHandsProc(msg, client_len, client_fd); 94 } 95 else 96 { 97 ;//...proc 98 } 99 close(client_fd); 100 } 101 close(server_fd); 102 }
客户端代码:
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 #include <unistd.h> 2 #include <arpa/inet.h> 3 #include <netinet/in.h> 4 #include <sys/socket.h> 5 #include <iostream> 6 #include <string.h> 7 #include <cstdlib> 8 #include <string> 9 #include <pthread.h> 10 using namespace std; 11 12 const short SHAKE_PORT = 9526; 13 const short CLIENT_PORT = 9527; 14 const int MAX_CONN_NUM = 5; 15 const string CLIENT_IP = "192.168.1.106"; 16 const int MAX_DATA_LENGTH = 255; 17 const int MSG_SHAKE_LENGTH = 20; 18 19 struct ShakeHands 20 { 21 int iConnID; 22 int iLength; //通信双方约定,iLength为20即为握手消息 23 int iSendID; 24 int iReceiveID; 25 char extend[4]; 26 27 void SwapID() 28 { 29 int tmp; 30 tmp = iSendID; 31 iSendID = iReceiveID; 32 iReceiveID = tmp; 33 } 34 }; 35 36 void* ShakeHands(void* arg) 37 { 38 struct ShakeHands msg; 39 msg.iConnID = 123; 40 msg.iLength = sizeof(struct ShakeHands); 41 msg.iSendID = 1; 42 msg.iReceiveID = 2; 43 int res; 44 45 sockaddr_in* pTmp = (sockaddr_in*)arg; 46 int shakefd = -1; 47 48 while(1) 49 { 50 shakefd = socket(AF_INET, SOCK_STREAM, 0); 51 cout << "Start to send shakehands" << endl; 52 res = connect(shakefd, (sockaddr*)pTmp, sizeof(*pTmp)); 53 if (-1 == res) 54 { 55 cerr << "connect failed" << std::endl; 56 sleep(1); 57 continue; 58 } 59 60 write(shakefd, &msg, msg.iLength); 61 memset(&msg, 0, sizeof(struct ShakeHands)); 62 read(shakefd, &msg, MAX_DATA_LENGTH); 63 if (MSG_SHAKE_LENGTH == msg.iLength) 64 { 65 cout << "shake hands succeed" << endl; 66 } 67 sleep(5); 68 } 69 close(shakefd); 70 pthread_exit(const_cast<char*>("exit")); 71 } 72 73 int main() 74 { 75 int sockfd = 0; 76 int len = 0; 77 struct sockaddr_in address; 78 char ch[MAX_DATA_LENGTH] = "Hello Server!"; 79 80 address.sin_family = AF_INET; 81 address.sin_port = htons(CLIENT_PORT); 82 address.sin_addr.s_addr = inet_addr("192.168.1.105"); 83 len = sizeof(address); 84 85 pthread_t m_thread; 86 void* result; 87 88 int res = pthread_create(&m_thread, NULL, ShakeHands, (void*)&address); 89 if (-1 == res) 90 { 91 cerr << "thread create failed"; 92 exit(EXIT_FAILURE); 93 } 94 95 //此处做主线程工作 96 97 res = pthread_join(m_thread, &result); 98 if (0 != res) 99 { 100 cerr << "thread join failed"; 101 exit(EXIT_FAILURE); 102 } 103 104 105 exit(EXIT_SUCCESS); 106 }