MENU

网络聊天程序的设计与实现

December 16, 2019 • 阅读: 3827 • 笔记&折腾



基于 Socket 通信原理。原理请点击 Socket

目录:

1、添加库

编辑环境为 CodeBlocks。首先添加要用的库。

具体操作为:Settings --> Compiler Settings --> Linker settings,然后点击 Add,找到路径 E:\CodeBlocks\MinGW\lib\libws2_32.a (根据 CB 安装的路径不同自行改变),在右侧输入 -lws2_32,点击 OK 保存,重启 CodeBlocks 添加成功。

2、代码

Server.cpp

  • #include <stdio.h>
  • #include <Winsock2.h>
  • #pragma comment(lib, "WS2_32") // 链接到WS2_32.lib
  • using namespace std;
  • #include <fstream>
  • #include <string>
  • #include <iostream>
  • DWORD WINAPI RECVm(void *Param){
  • char sendBuf[50];//缓冲区
  • char recvBuf[50];//缓冲区
  • char username[50]={0}; // 用户名
  • SOCKET sockConn = *((SOCKET *)Param);
  • strcpy(sendBuf,"Join in chatroom success!You can start chatting...\n");
  • send(sockConn,sendBuf,strlen(sendBuf)+1,0);//将数据原样返回
  • recv(sockConn,recvBuf,50,0);
  • strcpy(username,recvBuf);
  • printf("%s has join in chatting room.\n",username);
  • while(1)
  • {
  • //接收
  • if(recv(sockConn,recvBuf,50,0)<=0){
  • printf("%s has exit!\n",username);
  • break;
  • }
  • if(recvBuf!=""){
  • printf("%s: %s\n",username,recvBuf);
  • }
  • strcpy(recvBuf,"");
  • }
  • closesocket(sockConn);
  • //closesocket(sockSrv);
  • return 0;
  • }
  • int main()
  • {
  • printf("Welcome to chatting room.....\n");
  • WORD wVersionRequested;//wVersionRequested 是我们要求使用的 WinSock 的版本。
  • WSADATA wsaData;
  • int err;
  • wVersionRequested = MAKEWORD( 1, 1 );
  • err = WSAStartup( wVersionRequested, &wsaData );
  • if ( err != 0 ){
  • return 0;}
  • if ( LOBYTE( wsaData.wVersion ) != 1 || HIBYTE( wsaData.wVersion ) != 1 ){
  • WSACleanup( );
  • return 0;}
  • //创建套接字
  • SOCKET sockSrv=socket(AF_INET,SOCK_STREAM,0);
  • //创建sockaddr_in结构体变量,绑定套接字
  • SOCKADDR_IN addrSrv;
  • addrSrv.sin_addr.S_un.S_addr=inet_addr("127.0.0.1");//通讯地址
  • addrSrv.sin_family=AF_INET; //sin_family必须为AF_INET,ipv4
  • addrSrv.sin_port=htons(6000); //端口号
  • //将套接字和 IP,端口 绑定
  • bind(sockSrv,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));
  • //进入监听状态,后台等待连接队列的最小限制值5
  • listen(sockSrv,5);
  • //接收
  • SOCKADDR_IN addrClient;
  • int len=sizeof(SOCKADDR);
  • while(1){
  • SOCKET sockConn=accept(sockSrv,(SOCKADDR*)&addrClient,&len);
  • CreateThread(NULL,0,RECVm,&sockConn,0,NULL);
  • }
  • }

Client.cpp

  • #include <iostream>
  • #include <stdio.h>
  • #include <Winsock2.h>
  • #pragma comment(lib, "WS2_32")
  • using namespace std;
  • //
  • int main()
  • {
  • //初始化
  • WORD wVersionRequested; //版本
  • WSADATA wsaData;
  • int err;
  • wVersionRequested = MAKEWORD( 1, 1 ); //主版号为1,副版号为1
  • err = WSAStartup( wVersionRequested, &wsaData );
  • if ( err != 0 )
  • {
  • return 0;
  • }
  • if ( LOBYTE( wsaData.wVersion ) != 1 || HIBYTE( wsaData.wVersion ) != 1 )
  • {
  • WSACleanup( );
  • return 0;
  • }
  • //创建套接字
  • SOCKET sockClient=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(6000);
  • //创建连接
  • connect(sockClient,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));
  • //发送
  • char yourname[50]={0};
  • printf("Please enter your username: ");
  • gets(yourname);
  • send(sockClient,yourname,strlen(yourname)+1,0);
  • char recvBuf[50];
  • recv(sockClient,recvBuf,50,0);
  • printf("Response: %s\n",recvBuf);
  • while(1){
  • printf("Enter Messages: ");
  • gets(yourname);
  • send(sockClient,yourname,strlen(yourname)+1,0);
  • //recv(sockClient,recvBuf,50,0);
  • //printf("Response: %s\n",recvBuf);
  • }
  • //char recvBuf[50];
  • //recv(sockClient,recvBuf,50,0);
  • //printf("Response: %s\n",recvBuf);
  • closesocket(sockClient);
  • WSACleanup();
  • }

3、运行程序

先运行 Server 程序,然后再运行 Client 程序,可运行多个 Client 程序,即一个服务端,多个客户端。

效果图:

Last Modified: February 6, 2021
Leave a Comment

4 Comments
  1. wang wang

    我来评论一下
    首先客户端退出后没做判断导致服务端死循环
    第二客户端没做接收消息处理
    第三无用代码写太多

    1. starMan starMan

      @wang 你说的没错,我会找时间修改的?

    2. starMan starMan

      @starMan 客户端的 BUG 已经修改

  2. Ashen one Ashen one

    test