18-群聊服务器与客户端联调

群聊服务器与客户端联调

客户端设计思路:

  • 客户端请求链接服务器上线

  • 客户端等待用户的输入

  • 客户端等待服务端消息

  • 等待客户端自己下线

线程任务

  • 发送线程:用于向服务器发送信息

  • 接收线程:等待服务器传回消息

完整代码

#include<stdio.h>
#include<Windows.h>
#include<process.h>
#pragma comment(lib,"ws2_32.lib")

#define NAME_SIZE 256
#define MAX_BUF_SIZE 1024

char szName[NAME_SIZE] = "[DEFAULT]"; //默认昵称
char szMsg[MAX_BUF_SIZE] = "[DEFAULT]"; //收发数据的BUF

unsigned WINAPI sendMsg(void* arg)
{
SOCKET hClntSock = *((SOCKET*)arg);
char szNameMsg[NAME_SIZE + MAX_BUF_SIZE] = { 0 };
while (1)
{
memset(szMsg, 0, MAX_BUF_SIZE);
fgets(szMsg, MAX_BUF_SIZE,stdin);
if (!strcmp(szMsg, "Q\n") || !strcmp(szMsg, "q\n"))
{
closesocket(hClntSock);
exit(0);
}
sprintf(szNameMsg, "%s %s", szName, szMsg);
send(hClntSock, szNameMsg, strlen(szNameMsg), 0);

}
closesocket(hClntSock);
return 0;
}

unsigned WINAPI RecvMsg(void* arg)
{
SOCKET hClntSock = *((SOCKET*)arg);
int iLen = 0;
char szNameMsg[NAME_SIZE + MAX_BUF_SIZE] = { 0 };
while (1)
{
memset(szMsg, 0, MAX_BUF_SIZE);
iLen = recv(hClntSock, szNameMsg, sizeof(szNameMsg), 0);
if (iLen == -1)
{
return -1;
}
szNameMsg[iLen] = 0;
fputs(szNameMsg, stdout);

}
closesocket(hClntSock);
return 0;
}

int main(int argc,char* argv[])
{
if (argc != 2)
{
printf("必须输入2个参数,例如昵称\n");
printf("进入程序的当前目录,按住shift+右击,打开powershell,输入参数\n");
printf("例如:Client.exe Jay\n");
system("pause");
return -1;
}
sprintf(szName, "[%s]", argv[1]);
HANDLE hSendThread, hRecvThread;
SOCKET hServer;
SOCKADDR_IN servAdr;
WORD wVersionRequested;
WSADATA wsadata;
int err;
wVersionRequested = MAKEWORD(2, 2);

err = WSAStartup(wVersionRequested, &wsadata);
if (err)
{
printf("WSAStartup errnum: %d\n", GetLastError());
return err;
}

if (LOBYTE(wsadata.wVersion) != 2 || HIBYTE(wsadata.wVersion) != 2)
{
printf("LOBYTE errnum: %d\n", GetLastError());
WSACleanup();
return -1;
}

SOCKET sockCli;
sockCli = socket(AF_INET, SOCK_STREAM, 0);
SOCKADDR_IN addrSrv;
addrSrv.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
addrSrv.sin_family = AF_INET;
addrSrv.sin_port = htons(9999);


if (SOCKET_ERROR == connect(sockCli, (sockaddr*)&addrSrv, sizeof(sockaddr)))
{
printf("%d", GetLastError());
return -1;
}

hSendThread = (HANDLE)_beginthreadex(NULL, 0, &sendMsg, (void*)&sockCli, 0, NULL);
hRecvThread = (HANDLE)_beginthreadex(NULL, 0, &RecvMsg, (void*)&sockCli, 0, NULL);

WaitForSingleObject(hSendThread,INFINITE);

WaitForSingleObject(hRecvThread, INFINITE);
closesocket(hServer);
return 0;
}