直接上代码,让代码说话!
//Server.h
#pragma once
#include <stdio.h>
#include <iostream>
#include <winsock2.h>
#include <map>
#pragma comment (lib, "ws2_32.lib")
using namespace std;
#define SERVER_HOST "XX.X.XX.XX"
enum Type { HEART, CTRL_INFO, OTHER};
//packet
struct PACKET
{
//报文头
Type type;
//报文信息
char msg[1024];
};
class Server
{
public:
Server();
//construction
Server(string ip, int port);
//deconstruction
~Server();
//
void Bind();
//
void Accept();
//
void Listen(int queue_len);
//
void Recv();
//
void Run();
//心跳线程入口函数
static UINT HeartProc(LPVOID lparam);
private:
sockaddr_in m_serverAddr;
//监听fd
int m_listen_fd;
//最大监听fd
int m_max_fd;
//超时信息
timeval m_timeout;
//所有fd集合,包括监听fd和客户端fd
fd_set m_master_set;
//工作集合
fd_set m_working_set;
//Server Thread
CWinThread* m_serverThread;
public:
//记录链接的客户端信息,链接、IP、未发送心跳次数
map<int, pair<string, int> > m_clientInfo;
};
//Server.cpp
#include "stdafx.h"
#include "Server.h"
#include <Ws2tcpip.h>
Server::Server(string ip, int port)
{
m_serverThread = NULL;
//
WSADATA wsaData;
// Initialize Windows socket library
WSAStartup(0x0202, &wsaData);
//先将保存地址的server置为全0
memset(&m_serverAddr, 0, sizeof(SOCKADDR_IN));
//
m_serverAddr.sin_family = AF_INET;
m_serverAddr.sin_addr.s_addr = inet_addr(ip.c_str());
m_serverAddr.sin_port = htons(port);
// create socket to listen
m_listen_fd = socket(PF_INET, SOCK_STREAM, 0);
if (m_listen_fd < 0)
{
//AfxMessageBox为MFC中的提示对话框接口
AfxMessageBox(_T("Create Socket Failed!"), MB_ICONINFORMATION);
//exit(1);
}
else{}
int opt = 1;
//closesocket(一般不会立即关闭而经历TIME_WAIT的过程)后想继续重用该socket
setsockopt(m_listen_fd, SOL_SOCKET, SO_REUSEADDR, (char*)&opt, sizeof(opt));
}
Server::Server()
{
}
Server::~Server()
{
for (int fd = 0; fd <= m_max_fd; ++fd)
{
if (FD_ISSET(fd, &m_max_fd))
Socket 客户端与服务端通信【心跳机制+断线重连】
最新推荐文章于 2024-09-08 10:21:15 发布
这是一个关于Socket通信的示例,涵盖了心跳机制和断线重连功能。通过创建Server和Client类,实现了服务器监听、接受客户端连接、发送与接收心跳报文。当客户端3秒内未收到心跳包,会判断为服务端掉线并尝试重新连接;服务器端如果5次未收到心跳包则认为客户端已下线。
摘要由CSDN通过智能技术生成