WinSock多人聊天客户端

描述

  1. 使用WinSock
  2. 使用CodeBlocks编译
  3. 只要需要运行两个客户端,客户端发送消息给服务端,服务端收到消息后转发给其他客户端
  4. 参考:https://www.cnblogs.com/imwtr/p/4072452.html

效果

代码

服务端

#include <stdlib.h>
#include <stdio.h>
#include <winsock2.h>
#include <time.h>
#include "conio.h"
#include <windows.h>
#include <process.h>
#include <math.h>
#include <iostream>
#define QLEN 5
#define WSVERS MAKEWORD(2, 2)
#define BUFLEN 2000
using namespace std;
SOCKET    msock, ssock;
SOCKET    sockets[100] = {
   NULL};

int cc;
char    *pts;
time_t    now;
char buf[2000];
char *input;
HANDLE hThread1,hThread[100] = {
   NULL};
unsigned int threadID,ThreadID[100],number;

struct    sockaddr_in fsin;
struct    sockaddr_in Sin;

unsigned int __stdcall Chat(PVOID PM)
{
   
    char buf1[2000];
    char buf2[2000];
    char buf3[2000];
    char buf4[2000];

    (void) time(&now);
    pts = ctime(&now);

    sockets[number] = ssock;

    SOCKET    sock = ssock;

    ThreadID[number] = threadID;

    unsigned int threadid = threadID;

    sprintf(buf1,"时间: %s当前线程ID: %d ,运行在:%s:%d\n",pts,threadid,inet_ntoa(fsin.sin_addr),fsin.sin_port);

    send(sock,buf1, sizeof(buf1), 0);

    sprintf(buf2,"线程ID: %d, 用户: %s:%d 进入了聊天室",threadid,inet_ntoa(fsin.sin_addr),fsin.sin_port);
    printf("%s ",buf2);

    for(int i=0; i<=number; i++)
    {
   
        if(sockets[i] != NULL && sockets[i] != sock)
        {
   
            send(sockets[i],buf2, sizeof(buf2), 0);
            cout<< "发送消息至线程 "<< ThreadID[i] << " 成功" <<endl;
        }
    }
    cout<< endl;


flag1:
    cc = recv(sock, buf3, BUFLEN, 0);
    if(cc == SOCKET_ERROR|| cc == 0)
    {
   

        sprintf( buf3,"线程ID: %d, 用户: %s:%d 离开了聊天室",threadid,inet_ntoa(fsin.sin_addr),fsin.sin_port);
        sock = NULL;
        sockets[number] = NULL;
        CloseHandle(hThread[number]);
        printf("%s ", buf3);
        for(int i=0; i<=number; i++)
        {
   
            if(sockets[i] != NULL && sockets[i] != sock)
            {
   
                (void) send(sockets[i], buf3, sizeof(buf3), 0);
                printf("发送至线程ID: %d成功!\n",ThreadID[i]);
            }
        }
        printf(" \n");
    }

    else if(cc > 0)
    {
   
        (void) time(&now);
        pts = ctime(&now);
        sprintf(buf4,"线程ID: %d, 用户%s:%d说: %s ",threadid,inet_ntoa(fsin.sin_addr),fsin.sin_port,buf3);

        printf("%s ",buf4);

        for(int i=0; i<=number; i++)
        {
   
            if(sockets[i] != NULL && sockets[i] != sock)
            {
   
                (void) send(sockets[i],buf4, sizeof(buf4), 0);
                printf("发送至线程ID: %d 成功 \n",ThreadID[i]);
            }
        }
        printf(" \n");

        goto flag1;
    }
    closesocket(sock);

    return 0;
}

int  main(int argc, char *argv[])
{
   
    int     alen;
    WSADATA wsadata;
    char    *service = "5050";

    WSAStartup(WSVERS, &wsadata);

    msock = socket(PF_INET, SOCK_STREAM, 0);

    memset(&Sin, 0, sizeof(Sin));

    Sin.sin_family = AF_INET;
    Sin.sin_addr.s_addr = INADDR_ANY;
    Sin.sin_port = htons((u_short)atoi(service));

    if( bind(msock, (struct sockaddr *)&Sin, sizeof(Sin)) == 0)
    {
   
        cout<< "服务端bind()成功,运行在端口:" << service << endl;
        if(listen(msock, 5) == 0)
        {
   
            cout<< "服务端listen()成功"<<endl;
            cout<< "聊天室已启动,请打开至少两个客户端开始聊天" <<endl;
        }
        else
        {
   
            cout<< "服务端listen()出错" << endl;
            WSACleanup();
            exit(0);
        }
    }
    else
    {
   
        cout<< "服务端bind()出错" << endl;
        WSACleanup();
        exit(0);
    }
    (void) time(&now);
    pts = ctime(&now);
    number = -1;
    while(1)
    {
   
        alen = sizeof(struct sockaddr);

        ssock = accept(msock, (struct sockaddr *)&fsin, &alen);

        number ++;

        hThread[number] = (HANDLE)_beginthreadex(NULL, 0,Chat,NULL, 0, &threadID);
    }

    closesocket(msock);

    WSACleanup();

    return 0;
}

客户端

#include <stdlib.h>
#include <stdio.h>
#include <winsock2.h>
#include <string.h>
#include <time.h>
#include <windows.h>
#include <process.h>
#include <math.h>
#include <iostream>
#define BUFLEN 2000
#define WSVERS MAKEWORD(2, 2)

using namespace std;


SOCKET    sock,sockets[100] = {
   NULL};
char *packet = NULL;
char *pts,*input;
HANDLE hThread;
unsigned threadID;

unsigned int __stdcall Chat(PVOID PM )
{
   
    time_t    now;
    (void) time(&now);
    pts = ctime(&now);
    char buf[2000];

    while(1)
    {
   
        int cc = recv(sock, buf, BUFLEN, 0);
        cout<< endl;
        if(cc == SOCKET_ERROR|| cc == 0)
        {
   

            cout<< "错误,与服务器断开连接" << GetLastError()<< endl;
            CloseHandle(hThread);
            (void)closesocket(sock);
            break;
        }
        else if(cc > 0)
        {
   
            printf("\n%s\n",buf);
        }
    }
    return 0;
}

int main(int argc, char *argv[])
{
   
    time_t    now;
    (void) time(&now);
    pts = ctime(&now);
    char    *host = "127.0.0.1";
    char *service = "5050";
    struct  sockaddr_in sin;

    WSADATA wsadata;

    WSAStartup(WSVERS, &wsadata);

    memset(&sin, 0, sizeof(sin));
    sin.sin_family = AF_INET;
    sin.sin_port = htons((u_short)atoi(service));
    sin.sin_addr.s_addr = inet_addr(host);

    sock = socket(PF_INET, SOCK_STREAM,0);

    connect(sock, (struct sockaddr *)&sin, sizeof(sin));

    printf("聊天室客户端(Client)已启动\n");
    hThread = (HANDLE)_beginthreadex(NULL, 0,Chat, NULL, 0, &threadID);

    while(1)
    {
   
        char buf1[2000];
        printf("请输入要发送的信息:");
// scanf("%s",&buf1);
        cin>> buf1;
        cout<< endl;
        if(!strcmp(buf1,"exit"))
            goto end;
        send(sock,buf1, sizeof(buf1), 0);
        cout<< endl;
    }

end:
    CloseHandle(hThread);
    closesocket(sock);
    WSACleanup();
    printf("按回车键继续...");
    getchar();
    return 0;
}

全部评论

相关推荐

点赞 1 评论
分享
牛客网
牛客企业服务