首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> 關於C++

控制台聊天程式範例:Winsock 多執行緒實作

     編輯:關於C++

網路上發現的控制台聊天程式範例,經修改整理收藏。採用 Winsock API、多執行緒處理收發訊息。

伺服器端程式碼


// 2009-06-28
#pragma comment(lib,"ws2_32.lib")
#include <winsock2.h>
#include <stdio.h>
#include <string>
using namespace std;

string strCurMsg = "";
void recvProc(SOCKET sockConnect) {
    char msgRcv[100] = {0};
    while (true) {
        if (SOCKET_ERROR == recv(sockConnect, msgRcv, sizeof(msgRcv), 0)) {
            printf("\nHe is leaving");
            return;
        }
        if (msgRcv[0] != '\0') {
            strCurMsg.erase(strCurMsg.end()-7, strCurMsg.end());
            strCurMsg += "He said: ";
            strCurMsg += msgRcv;
            strCurMsg += '\n';
            strCurMsg += "input: ";
            system("cls");
            printf("%s", strCurMsg.c_str());
        }
    }
}

int main(int argc, char* argv[]) {
    WORD wVersionRequested = MAKEWORD(1, 1);
    WSADATA wsaData;
    if (WSAStartup(wVersionRequested, &wsaData) != 0) return 1;
    if (LOBYTE(wsaData.wVersion) != 1 || HIBYTE(wsaData.wVersion) != 1) {
        WSACleanup(); return 1;
    }

    SOCKET sockSrv = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    sockaddr_in addrSrv = {0};
    addrSrv.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
    addrSrv.sin_family = AF_INET;
    addrSrv.sin_port = htons(5000);

    if (bind(sockSrv, (sockaddr*)&addrSrv, sizeof(sockaddr)) == SOCKET_ERROR) {
        printf("bind error"); return 1;
    }
    if (listen(sockSrv, 5) == SOCKET_ERROR) {
        printf("listen error"); return 1;
    }

    SOCKADDR_IN addrClient;
    int len = sizeof(sockaddr);
    while (true) {
        printf("Waiting ...");
        SOCKET sockConnect = accept(sockSrv, (sockaddr*)&addrClient, &len);
        if (sockConnect == INVALID_SOCKET) {
            printf("invalid socket"); return 0;
        } else {
            printf("He is coming\n");
        }
        CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)recvProc, (void*)sockConnect, 0, NULL);
        while (true) {
            char buf[100] = {0};
            strCurMsg += "input: ";
            system("cls");
            printf("%s", strCurMsg.c_str());
            gets_s(buf, 100);
            strCurMsg.erase(strCurMsg.end()-7, strCurMsg.end());
            strCurMsg += "You said:";
            strCurMsg += buf;
            strCurMsg += '\n';
            send(sockConnect, buf, sizeof(buf), 0);
        }
        closesocket(sockConnect);
    }
    WSACleanup();
    return 0;
}

客戶端程式碼


// 2009-06-28
#pragma comment(lib,"ws2_32.lib")
#include <winsock2.h>
#include <stdio.h>
#include <string>
using namespace std;

string strCurMsg = "";
void recvProc(SOCKET sockClient) {
    char msgRcv[100] = {0};
    while (true) {
        if (SOCKET_ERROR == recv(sockClient, msgRcv, sizeof(msgRcv), 0)) {
            printf("\nHe is leaving");
            return;
        }
        if (msgRcv[0] != '\0') {
            strCurMsg.erase(strCurMsg.end()-7, strCurMsg.end());
            strCurMsg += "He said: ";
            strCurMsg += msgRcv;
            strCurMsg += '\n';
            strCurMsg += "input: ";
            system("cls");
            printf("%s", strCurMsg.c_str());
        }
    }
}

int main(int argc, char* argv[]) {
    WORD wVersionRequested = MAKEWORD(1, 1);
    WSADATA wsaData;
    if (WSAStartup(wVersionRequested, &wsaData) != 0) return 1;
    if (LOBYTE(wsaData.wVersion) != 1 || HIBYTE(wsaData.wVersion) != 1) {
        WSACleanup(); return 1;
    }

    SOCKET sockClient = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    SOCKADDR_IN addrSrv = {0};
    addrSrv.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
    addrSrv.sin_family = AF_INET;
    addrSrv.sin_port = htons(5000);

    if (connect(sockClient, (sockaddr*)&addrSrv, sizeof(sockaddr)) == SOCKET_ERROR) {
        printf("connected failed\n"); return 1;
    } else {
        printf("connect OK\n");
    }

    CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)recvProc, (void*)sockClient, 0, NULL);
    while (true) {
        char buf[100] = {0};
        strCurMsg += "input: ";
        system("cls");
        printf("%s", strCurMsg.c_str());
        gets_s(buf, 100);
        strCurMsg.erase(strCurMsg.end()-7, strCurMsg.end());
        strCurMsg += "You said:";
        strCurMsg += buf;
        strCurMsg += '\n';
        send(sockClient, buf, sizeof(buf), 0);
    }
    closesocket(sockClient);
    WSACleanup();
    return 0;
}

注意:原始碼中 gets 已替換為較安全的 gets_s,實際使用建議進一步加強錯誤處理與資源管理。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved