• socket心跳+聊天


    简单的小程序,vs2015编译通过

    server

    #include <tchar.h>
    #include <winsock2.h>
    #include <stdio.h>
    #include <windows.h>
    #pragma comment(lib,"ws2_32.lib")
    #define PORT 2000 //端口号
    
    typedef struct                    /* message structure */
    {
        UINT16 type;
        char data[1024];
    } msg_t;
    
    #define MSG_TYPE1        1        /* application specific msg */
    #define MSG_TYPE2        2        /* another one */
    #define MSG_HEARTBEAT    3        /* heartbeat message */
    
    #define T1        60        /* idle time before heartbeat */
    #define T2        10        /* time to wait for response */
    int _tmain(int argc, _TCHAR* argv[])
    {
        WSADATA wsa;
        //初始化套接字DLL
        if (WSAStartup(MAKEWORD(2, 2), &wsa) != 0)
        {
            printf("套接字初始化失败!");
            exit(-1);
        }
    
        SOCKET serverSocket;
        if ((serverSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET)
        {
            printf("创建套接字失败!");
            exit(-1);
        }
        struct sockaddr_in serverAddress;
        memset(&serverAddress, 0, sizeof(sockaddr_in));
        serverAddress.sin_family = AF_INET;
        serverAddress.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
        serverAddress.sin_port = htons(PORT);
    
        if (bind(serverSocket, (sockaddr*)&serverAddress, sizeof(serverAddress)) == SOCKET_ERROR)
        {
            printf("套接字绑定到端口失败!端口: %d
    ", PORT);
            return -1;
        }
        //进入侦听状态
        if (listen(serverSocket, SOMAXCONN) == SOCKET_ERROR)
        {
            printf("侦听失败!");
            return -1;
        }
    
        printf("服务器端口: %d 正在监听......
    ", PORT);
        //非阻塞
        ULONG nonblock = 1;
        if (ioctlsocket(serverSocket, FIONBIO, &nonblock) == SOCKET_ERROR)
        {
            printf("ioctlsocket() failed with error %d
    ", WSAGetLastError());
            return -1;
        }
        SOCKET acceptSocket;//用来和客户端通信的套接字
        struct sockaddr_in clientAddress;//用来和客户端通信的套接字地址
        memset(&clientAddress, 0, sizeof(clientAddress));
        int addrlen = sizeof(clientAddress);
    
        //fd_set fdRead;
        fd_set fdSocket;
        FD_ZERO(&fdSocket);
        FD_SET(serverSocket, &fdSocket);
    
        struct timeval tv;
        tv.tv_sec = T1 + T2;
        tv.tv_usec = 0;
        int missed_heartbeats = 0;
    
    
        msg_t msg;
    
        while (true)
        {
            fd_set fdRead = fdSocket;
            int nRet = select(serverSocket + 1, &fdRead, NULL, NULL, &tv);
            if (nRet < 0)
            {
                printf("select失败
    ");
                break;
            }
            if (nRet == 0)        /* timed out */
            {
                if (++missed_heartbeats > 3)
                    printf("连续三个心跳未收到,可能服务器已挂
    ");
                printf("心跳未收到 #%d
    ", missed_heartbeats);
                tv.tv_sec = T2;
                continue;
            }
            else
            {
                for (int i = 0; i < (int)fdSocket.fd_count; i++)
                {
                    if (FD_ISSET(fdSocket.fd_array[i], &fdRead))
                    {
                        if (fdSocket.fd_array[i] == serverSocket)
                        {
                            if ((acceptSocket = accept(serverSocket, (sockaddr*)&clientAddress, &addrlen)) == INVALID_SOCKET)
                            {
                                printf("接受客户端连接失败!");
                                return -1;
                            }
                            ULONG nonblock = 1;
                            if (ioctlsocket(acceptSocket, FIONBIO, &nonblock) == SOCKET_ERROR)
                            {
                                printf("Socket异步配置错误 %d
    ", WSAGetLastError());
                                return -1;
                            }
                            FD_SET(acceptSocket, &fdSocket);
                            printf("建立连接成功
    ");
                        }
                        else
                        {
                            //nRet--;
                            acceptSocket = fdSocket.fd_array[i];
                            //char buf[1024];
                            //int cnt=sizeof(buf);
                            memset(&msg, 0, sizeof(msg));
                            int bytes;
                            //if ((bytes = recv(acceptSocket, buf, 2, 0)) == SOCKET_ERROR)
    
                            if ((bytes = recv(acceptSocket, (char *)&msg, sizeof(msg), 0)) == SOCKET_ERROR)
                            {
                                printf("接收数据失败!
    ");
                                return -1;
                            }
                            if (bytes > 0)
                            {
                                switch (ntohs(msg.type))
                                {
                                case MSG_TYPE1:
                                case MSG_TYPE2:
                                    printf("有消息来自 %s: %s
    ", inet_ntoa(clientAddress.sin_addr), msg.data);
                                    if (send(acceptSocket, (char *)& msg, sizeof(msg_t), 0) == SOCKET_ERROR)
                                    {
                                        printf("发送数据失败!");
                                        return -1;
                                    }
                                    missed_heartbeats = 0;
                                    tv.tv_sec = T1 + T2;
                                    break;
                                case MSG_HEARTBEAT:
                                    printf("收到心跳
    ");
                                    bytes = send(acceptSocket, (char *)&msg, sizeof(msg), 0);
                                    if (bytes < 0)
                                    {
                                        printf("心跳回送失败
    ");
                                        return -1;
                                    }
                                    missed_heartbeats = 0;
                                    tv.tv_sec = T1 + T2;
                                    break;
                                default:
                                    printf("未知类型
    ");
                                    closesocket(fdSocket.fd_array[i]);
                                    FD_CLR(fdSocket.fd_array[i], &fdSocket);
                                    break;
                                }
                            }
                            else
                            {
                                closesocket(fdSocket.fd_array[i]);
                                FD_CLR(fdSocket.fd_array[i], &fdSocket);
                            }
                        }
                    }
                }
            }
        }
        //清理套接字占用的资源
        WSACleanup();
        return 0;
    }

    client

    #include <tchar.h>
    #include <winsock2.h>
    #include <stdio.h>
    #include <windows.h>
    #include <process.h>
    #pragma comment(lib,"ws2_32.lib")
    #define  PORT 2000
    
    typedef struct                    /* message structure */
    {
        UINT16 type;
        char data[1024];
    } msg_t;
    
    #define MSG_TYPE1        1        /* application specific msg */
    #define MSG_TYPE2        2        /* another one */
    #define MSG_HEARTBEAT    3        /* heartbeat message */
    
    #define T1        6        /* idle time before heartbeat */
    #define T2        1        /* time to wait for response */
    
    DWORD WINAPI listenFunc(PVOID pvParam) {
        SOCKET sock = *((SOCKET*)pvParam);
        fd_set fdSocket;
        FD_ZERO(&fdSocket);
        FD_SET(sock, &fdSocket);
        struct timeval tv;
        tv.tv_sec = T1;
        tv.tv_usec = 0;
        int missed_heartbeats = 0;
        msg_t msg;
        int length;
        while (1)
        {
            fd_set fdRead = fdSocket;
            int nRet = select(sock + 1, &fdRead, NULL, NULL, &tv);
            if (nRet == 0)        /* timed out */
            {
                if (++missed_heartbeats > 3)
                {
                    printf("连续三个心跳未收到,可能服务器已挂
    ");
                }
                printf("发送心跳 #%d
    ", missed_heartbeats);
                msg.type = htons(MSG_HEARTBEAT);
                if (send(sock, (char*)&msg, sizeof(msg), 0) == SOCKET_ERROR)
                {
                    printf("发送数据失败!");
                    return -1;
                }
                tv.tv_sec = T2;
                continue;
            }
            else
            {
                memset(&msg, 0, sizeof(msg));
                int bytes;
                if ((bytes = recv(sock, (char *)&msg, sizeof(msg), 0)) == SOCKET_ERROR)
                {
                    printf("接收数据失败!
    ");
                    return -1;
                }
                if (bytes > 0)
                {
                    switch (ntohs(msg.type))
                    {
                    case MSG_TYPE1:
                    case MSG_TYPE2:
                        printf("有消息来: %s
    ", msg.data);
                        break;
                    case MSG_HEARTBEAT:
                        printf("收到心跳
    ");
                        break;
                    default:
                        printf("未知类型
    ");
                        closesocket(sock);
                        FD_CLR(sock, &fdSocket);
                        break;
                    }
                    missed_heartbeats = 0;
                    tv.tv_sec = T1 + T2;
                }
                else
                {
                    closesocket(sock);
                    FD_CLR(sock, &fdSocket);
                }
            }
        }
    }
    
    int _tmain(int argc, _TCHAR* argv[])
    {
        WSADATA wsa;
        //初始化套接字DLL
        if (WSAStartup(MAKEWORD(2, 2), &wsa) != 0)
        {
            printf("套接字初始化失败!");
            return -1;
        }
    
        SOCKET sock;
        if ((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET)
        {
            printf("创建套接字失败!");
            return -1;
        }
        //char ipaddr[100];
        //printf("请输入对方ip地址:");
        //gets(ipaddr);
        struct sockaddr_in serverAddress;
        memset(&serverAddress, 0, sizeof(sockaddr_in));
        serverAddress.sin_family = AF_INET;
        serverAddress.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
        serverAddress.sin_port = htons(PORT);
    
        if (connect(sock, (sockaddr*)&serverAddress, sizeof(serverAddress)) == SOCKET_ERROR)
        {
            printf("建立连接失败!");
            return -1;
        }
    
        ULONG nonblock = 1;
        if (ioctlsocket(sock, FIONBIO, &nonblock) == SOCKET_ERROR)
        {
            printf("ioctlsocket() failed with error %d
    ", WSAGetLastError());
            return -1;
        }
    
        _beginthreadex(NULL, 0, (unsigned int(__stdcall *)(void *))listenFunc, &sock, 0, NULL);
    
        msg_t msg;
        memset(&msg, 0, sizeof(msg));
    
        while (true)
        {
            gets_s(msg.data);
            msg.type = htons(MSG_TYPE1);
            if (send(sock, (char*)&msg, sizeof(msg), 0) == SOCKET_ERROR)
            {
                printf("发送数据失败!");
                return -1;
            }
        }
        //清理套接字占用的资源
        WSACleanup();
        return 0;
    }
  • 相关阅读:
    More Effective C++ 条款34 如何在一个程序中结合C++和C
    More Effective C++ 条款33 将非尾端(non-leaf classes)设计为抽象类(abstract classes)
    More Effective C++ 条款32 在未来时态下发展程序
    win10子系统Ubuntu18.04下安装图形界面
    转载:Intel MKL 稀疏矩阵求解PARDISO 函数
    免费电子书下载
    Parallel Studio XE 调用 BLAS95 + LAPACK95 + IMSL
    linux后台运行和关闭、查看后台任务
    (转载)nohup命令让Linux程序永远在后台执行
    Linux 基本系统信息查询
  • 原文地址:https://www.cnblogs.com/leisurely/p/4584786.html
Copyright © 2020-2023  润新知