网络编程基础_5.2聊天室-单聊服务器

聊天室-单聊服务器

#include <stdio.h>

// 1. 包含必要的头文件和库, 必须位于 windows之前
#include <WinSock2.h>
#pragma comment(lib, "ws2_32.lib")

#include <windows.h>
#include <ws2tcpip.h>


// 工具函数,用于判断是否执行成功
VOID CheckResult(BOOL Value, LPCWSTR ErrMsg)
{
    // 如果 Value 非空,就表示执行成功
    if (Value == FALSE)
    {
        printf("ErrMsg: %ls\n", ErrMsg);
        system("pause"); ExitProcess(0);
    }
}


// 用于执行接收数据的线程
DWORD WINAPI ThreadRoutine(LPVOID lpThreadParameter)
{
    // 用于保存接收的数据
    CHAR Buffer[0x100] = { 0 };

    // 1. 获取到套接字的句柄
    SOCKET Socket = (SOCKET)lpThreadParameter;

    // 2. 在循环中不断的接收数据,如果返回值为
    while (recv(Socket, Buffer, 0x100, 0) > 0)
    {
        // 输出数据
        printf("Server: %s\n", Buffer);
    }

    return 0;
}

int main()
{
    // 2. 初始化网络环境并判断是否成功[ 搜索信号(2G?3G?4G?) ]
    WSAData WsaData = { 0 };
    if (!WSAStartup(MAKEWORD(2, 2), &WsaData))
        CheckResult(WsaData.wVersion == 0x0202, L"初始化网络环境失败");

    // 3. 创建套接字(IP+PORT) [ 买手机 ]
    SOCKET ServerSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    CheckResult(ServerSocket != INVALID_SOCKET, L"套接字创建失败");

    // 4. 绑定套接字,提供IP和端口 (办手机卡)
    sockaddr_in ServerAddr = { 0 };
    ServerAddr.sin_port = htons(0x1515);        // 端口
    ServerAddr.sin_family = AF_INET;            // 协议类型
    inet_pton(AF_INET, "127.0.0.1", &ServerAddr.sin_addr.S_un);
    BOOL Result = bind(ServerSocket,    // 要绑定的套接字
        (SOCKADDR*)& ServerAddr,        // 服务器的地址和IP对应的结构体
        sizeof(sockaddr_in));            // 必须要指定大小
    CheckResult(Result != SOCKET_ERROR, L"套接字绑定失败");

    // 5. 监听套接字 (开机,等待连接)
    // -  监听谁,最多等待多少个客户端的链接
    Result = listen(ServerSocket, SOMAXCONN);

    // 6. 等待客户端的连接(接电话)
    int dwSize = sizeof(sockaddr_in);
    sockaddr_in ClientAddr = { 0 };        // 接收的客户端ip和端口
    SOCKET ClientSocket = accept(ServerSocket,
        (SOCKADDR*)& ClientAddr, &dwSize);

    // 7. 创建线程用于执行接收数据的操作,将套接字句柄作为参数传入
    CreateThread(NULL, NULL, ThreadRoutine, (LPVOID)ClientSocket, NULL, NULL);

    // 8. 在循环中不断的发送数据
    CHAR Buffer[0x100] = { 0 };
    while (scanf_s("%s", Buffer, 0x100) && strcmp(Buffer, "quit"))
    {
        // 发送输入的数据
        send(ClientSocket, Buffer, strlen(Buffer) + 1, 0);
    }

    // 9. 关闭套接字执行清理工作
    shutdown(ClientSocket, SD_BOTH);
    closesocket(ClientSocket);
    closesocket(ServerSocket);

    // 10. 清理网络环境
    WSACleanup();

    system("pause");
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/ltyandy/p/10945999.html