【计算机网络】大作业-实现两台pc间交流的简单的聊天软件

参考

传送门 - 1 - csdn - 2112222222222
传送门 - 2 - bilibili - 憧憬少
传送门 - 3 -

要求

  1. 开发一个聊天程序
  2. 包含客户端和服务器段
  3. 编程语言不限
  4. 要能在两台PC机上运行

如何实现

通过 socket 实现 两台pc之间的聊天

什么是socket

  • Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口。
  • 在设计模式中,Socket其实就是一个门面模式,它把复杂的TCP/IP协议族隐藏在Socket接口后面,对用户来说,一组简单的接口就是全部,让Socket去组织数据,以符合指定的协议。

socket 是如何连接的

  1. 服务器端先初始化Socket
  2. 然后与端口绑定(bind),对端口进行监听(listen),调用accept阻塞,等待客户端连接。
  3. 在这时如果有个客户端初始化一个Socket,然后连接服务器(connect)
  4. 如果连接成功,这时客户端与服务器端的连接就建立了
  5. 客户端发送数据请求,服务器端接收请求并处理请求,然后把回应数据发送给客户端,客户端读取数据
  6. 最后关闭连接,一次交互结束。

参考文档:传送门

实现环境

  1. Visual Studio 2013
  2. windows 7 (机房电脑)

相关问题解决

解决 mircsoft visual studio 2013 无法打开 winsock2.h 头文件

  1. 确保
#pragma comment (lib, "ws2_32.lib") // 链接ws2_32.lib文件

该语句放置在前面,首先链接ws2_32.lib文件

  1. 打开 项目
    在这里插入图片描述
    选择 项目属性
    在这里插入图片描述配置属性调整平台工具集为XP那一项
    在这里插入图片描述
    记得点击应用,然后确定

解决无法打开 “stdafx.h” 文件的问题

microsoft visual studio 2013版本已经提前帮助项目预编译该文件了,所以不需要include
在这里插入图片描述

编译运行产生方法不安全提示时解决办法

在这里插入图片描述
server于client都将SDL检查设置为否

结果代码

服务器端代码

//server
#pragma comment(linker, "/STACK:36777216")
//#pragma GCC optimize ("O2") 
/**
*    This code has been written by YueGuang, feel free to ask me question. Blog: http://www.moonl1ght.xyz
*    created:
*/
#define LOCAL
#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>//#include <tr1/unordered_set>
//#include <tr1/unordered_map>
//#include <array>using namespace std;// un template header#pragma comment (lib, "ws2_32.lib") // 链接ws2_32.lib文件
#include <Winsock2.h> //windows socket编程头文件//自定义头文件//}/* .................................................................................................................................. *//*
bug 说明区域
1.颜色设置setcolor还不能使用
*//*
变量解释说明区域 QAQ
*/// 全局常量
const int BUF_SIZE = 2048;
const int SEND_SIZE = 1000;
const int MAX_BUF_SIZE = 500;
const int NICKNAME_LEN = 20;
const int MAX_CLIENT_COUNT = 20;// 全局变量
SOCKET sockSer, sockCli;
SOCKADDR_IN addrSer, addrCli;// address 地址  客户端地址和服务器地址
SOCKET NewConnection; //用于接受来自客户端的链接int clientCount = 0;
int naddr = sizeof(SOCKADDR_IN);
int Ret;
char sendbuf[BUF_SIZE];
char inputbuf[BUF_SIZE];
char recvbuf[BUF_SIZE];//该结构体的目的是允许多台PC机对服务器进行访问//全局函数using namespace std;int main(){//\第一步,加载socket函数,载入socket库WSADATA wsaData;if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0){//setColor(COLOR_ERROR);cout << "呐呐呐,载入socket库失败!" << '\n';system("pause");return 0;}//\第二步,创建一个监听套接字sockser, 创建socket(地址描述(AF_INET格式 - ipv4),指定socket类型(使用的是流式套接字即TCP协议), 指定协议if ((sockSer = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET){printf("当前为无效套接,程序结束");system("pause");return 0;}//\第三步,初始化服务器的地址包,填写相关信息/**	1.AF_INET优先赋值,这是由于该值是告诉winsock我们使用的是ip地址簇*	2.填写用来通讯的ip地址*	3.填写端口号**/char ip[] = "192.168.81.90";cout << "呐呐呐,本地IP是" << ip << "该电脑已经开启!\n";addrSer.sin_family = AF_INET;addrSer.sin_port = htons(5000);addrSer.sin_addr.S_un.S_addr = htonl(INADDR_ANY);//\第四步,将创建的sockser套接字和上面填写的相关地址信息绑定在一起,bind函数有很多,我们要选择的是sock中的所以加头文件的时候要注意不要多加if (bind((SOCKET)sockSer, (SOCKADDR *)&addrSer, sizeof(addrSer)) == SOCKET_ERROR){printf("BIND_ERROR: %d\n", SOCKET_ERROR);return 0;}cout << "二次元世界连接成功!" << endl;//\第五步,让服务器Socket开启监听,并且设置最大的等待连接数,等待连接数(半连接)过大会给服务器造成负载if (listen(sockSer, 5) == SOCKET_ERROR){printf("LISTEN_ERROR: %d\n", SOCKET_ERROR);system("pause");return 0;}//\第六步,客户端连接到达时,本服务器需接受连接,注意接受链接用的是客户端的变量即Cliint ClientAddrLen = sizeof(addrCli);printf("正在接受连接...");if ((NewConnection = accept(sockSer, (SOCKADDR *)&addrCli, &ClientAddrLen)) == INVALID_SOCKET){printf("ACCPET_ERROR: %d\n", INVALID_SOCKET);closesocket(sockSer);return 0;}printf("检测到一个来自三次元的连接: %s 端口:%d\n", inet_ntoa(addrCli.sin_addr), ntohs(addrCli.sin_port));//\第七步,开始接听,true情况下进程不关闭就不会结束,但需要考虑电脑while (true){//接收数据Ret = recv(NewConnection, recvbuf, BUF_SIZE, 0);if (Ret > 0)printf("JOJO对你说: %s\n", recvbuf);else if (Ret < 0)printf("RECV_ERROR: %d\n", SOCKET_ERROR);else{printf("对方觉得二次元浓度过高,退出了聊天!");break;}//发送数据printf("\n说:");scanf("%s", sendbuf);if (strcmp(sendbuf, "quit") == 0)   //退出break;if (send(NewConnection, sendbuf, BUF_SIZE, 0) == SOCKET_ERROR){printf("消息发送失败!\n");break;}}//关闭连接shutdown(NewConnection, SD_BOTH);closesocket(NewConnection);//关闭socket库closesocket(sockSer);//清空加载项if (WSACleanup() == SOCKET_ERROR){printf("WSACLEANUP_ERROR: %d\n", WSAGetLastError());return 0;}system("pause");return 0;
}

客户端代码

#pragma comment(linker, "/STACK:36777216")
//client
//client
#pragma comment(linker, "/STACK:36777216")
//#pragma GCC optimize ("O2") 
/**
*    This code has been written by YueGuang, feel free to ask me question. Blog: http://www.moonl1ght.xyz
*    created:
*/#include <algorithm>
#include <iostream>
#include <stdlib.h>
#include <stdio.h>//#include <tr1/unordered_set>
//#include <tr1/unordered_map>
//#include <array>using namespace std;// un template header#pragma comment (lib, "ws2_32.lib") // 链接ws2_32.lib文件
#include <Winsock2.h> //windows socket编程头文件/*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*///全局常量
const int BUF_SIZE = 2048;
const int SEND_SIZE = 1000;
const int MAX_BUF_SIZE = 200;//全局变量
SOCKET sockSer, sockCli;
SOCKADDR_IN addrSer, addrCli;// address 地址  客户端地址和服务器地址
int naddr = sizeof(SOCKADDR_IN);
char sendbuf[BUF_SIZE];
char inputbuf[BUF_SIZE];
char recvbuf[BUF_SIZE];
int Ret;//全局函数
// 接收线程的设置是死循环不断得提交recv申请,如果有反馈,就输出。
DWORD WINAPI Client_Receive_Thread(LPVOID lp) {SOCKET *s = (SOCKET*)lp;int nrecv;while (true){// 监听服务器端消息char recvBuf[SEND_SIZE]; //注意使用的是 B// recv 的第一个参数是当前socketint res = recv(sockCli, recvBuf, SEND_SIZE, 0); // 最后参数设置成0,表示非阻塞if (res > 0) // 由于socket默认的阻塞,因此recv会自动阻塞{printf("%s\n", recvBuf);}}
}int main(){//\加载socket函数,载入socket库WSADATA WSAData;if (WSAStartup(MAKEWORD(2, 2), &WSAData) != 0){//setColor(COLOR_ERROR);cout << "呐呐呐,载入socket库失败!" << '\n';system("pause");return 0;}char ip[] = "192.168.81.90";cout << "呐呐呐,本地IP是" << ip << "该电脑已经开启!\n";//setColor(COLOR_NORMAL);//初始化服务器地址addrSer.sin_family = AF_INET;addrSer.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");addrSer.sin_port = htons(5000);//创建socket(地址描述(AF_INET格式 - ipv4),指定socket类型(使用的是流式套接字即TCP协议), 指定协议sockSer = socket(AF_INET, SOCK_STREAM, 0);//建立连接if (connect(sockSer, (SOCKADDR *)&addrSer, sizeof(SOCKADDR)) == SOCKET_ERROR){cout << "CONNECT_ERROR : " << SOCKET_ERROR << endl;return 0;}else{cout << "二次元世界,连接成功!" << endl;}//读取用户名char username[50];printf("请输入您的用户名: ");scanf("%s", username);const int max_connet_cnt = 20; //最大尝试连接次数int cnt = 0;while (true){//发送数据cout << '\n' << username << "说:";cin >> sendbuf;if (strcmp(sendbuf, "quit") == 0){break;}if (send(sockSer, sendbuf, BUF_SIZE, 0) == SOCKET_ERROR){cout << "消息发送失败" << endl;break;}//接收数据Ret = recv(sockSer, recvbuf, BUF_SIZE, 0);if (Ret < 0){cout << "RECV_ERROR" << SOCKET_ERROR << endl;break;}else if (Ret == 0){cout << "对方退出聊天程序,聊天结束" << endl;break;}else{cout << "Server对你说:" << recvbuf << endl;}}//关闭socket库closesocket(sockSer);closesocket(sockCli);WSACleanup(); //清空加载项return 0;
}

运行截图1

在这里插入图片描述

获取本地IP的函数

void getLocalIP(char localIp[], int n){gethostname(localIp, n);HOSTENT *host = gethostbyname(localIp);in_addr PcAddr;int i = 0;while (true){char * p = host->h_addr_list[i];if (p == NULL){break;}memcpy(&(PcAddr, S_un.S_addr), p, host->h_length);strcpy(localIp, inet_ntoa(PcAddr));}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/48949.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

CSAPP家庭作业答案7 8 9章

答案仅供参考 7.12 解题思路是模仿链接器的行为:使用重定位记录来识别位置然后使用图7.9中的算法计算重新定位的绝对地址&#xff0c;或者简单地从图7.10中的重定位指令中提取它们。有两点需要注意的是第8行的movl指令包含两个需要重定位的引用。第5行和第8行的指令包含对buf…

asp毕业设计—— 基于asp+access的网上聊天室设计与实现(毕业论文+程序源码)——网上聊天室

基于aspaccess的网上聊天室设计与实现&#xff08;毕业论文程序源码&#xff09; 大家好&#xff0c;今天给大家介绍基于aspaccess的网上聊天室设计与实现&#xff0c;文章末尾附有本毕业设计的论文和源码下载地址哦。需要下载开题报告PPT模板及论文答辩PPT模板等的小伙伴&…

基于SSH开发酒店客房管理系统+论文+任务书+PPT 课程设计 毕业设计

基于SSH开发酒店客房管理系统论文任务书PPT&#xff08;大作业/毕业设计&#xff09; 开发环境: Windows操作系统 开发工具&#xff1a;MyeclipseJdkTomcatMysql数据库 运行效果图&#xff1a; 基于SSH开发酒店客房管理系统论文任务书PPT&#xff08;大作业/毕业设计&#xff0…

基于Android的相关毕业设计和论文

基于Android的相关毕业设计和论文 今年整理了一下关于基于android的相关毕业设计的信息&#xff0c;这里和大家分享一下&#xff0c;总共分为5大模块&#xff1a; 一、基于android的毕业设计题目整理&#xff0c;供大家学习参考 基于Android的消防网格化管理系统设计 基于An…

一大波嵌入式毕业设计选题推荐(配套源码、文档、开发板)

可以在本文的末尾免费领取,以下所有项目配套的文档及源码~ 嵌入式毕业设计选题推荐一&#xff1a;智能猫眼 项目功能介绍&#xff1a; 1. 人脸识别&#xff1a;基于百度专业的深度学习算法和海量数据训练可进行人脸识别&#xff0c;轻松知晓访客身份&#xff1b; 2. 智能报警&a…

毕业设计——基于Qt的酒店在线管理系统客户端开发与设计

Qt版百度网盘链接&#xff1a;https://pan.baidu.com/s/122951Yta-rXSBNafS3ndlg 提取码&#xff1a;r2qq C#版链接&#xff1a;https://blog.csdn.net/qq_40945965/article/details/90229681 另一篇博文&#xff1a;基于Qt的酒店管理系统&#xff08;毕业设计&#xff09; 基…

日赚1.7亿!华为发布2020年度财报!附华为十大5G应用场景

今日&#xff0c;华为发布2020年年度报告。 公告显示&#xff1a;销售收入8,914亿元人民币&#xff0c;同比增长3.8%&#xff0c;净利润646亿元人民币&#xff0c;同比增长3.2%。 按一年365天来算&#xff0c;华为平均日赚1.7亿人民币&#xff01; 华为今日还公布了关于公司轮值…

3·8 妇女节特别策划 | 对话开源社里的“半边天”:多彩的她们,有别样的力量~...

三八妇女节 Womens Day < 2023/03/08 > 01 职场女性 陈阳 开源社理事长、微软云计算机与人工智能事业部首席产品经理 一句话介绍自己&#xff1a; 开源社区中的二进制女性 向上滑动阅览采访 Q1&#xff1a;能介绍一下自己目前正在做的职业或者项目嘛&#xff1f; 白天在…

出门问问冲刺IPO:年营收5亿 要做港股AIGC第一股

雷递网 雷建平 5月31日 AI公司出门问问&#xff08;Mobvoi Inc.&#xff09;日前递交招股书&#xff0c;准备在港交所上市。 当前&#xff0c;港股市场缺少AIGC概念&#xff0c;一旦上市&#xff0c;出门问问将成为港股AIGC第一股。 亚洲起步最早 年营收5亿 出门问问是一家以生…

数学奥赛VS信息奥赛 | 为孩子选择更好地升学之路!

随着社会的不断发展&#xff0c;在孩子成长学习中&#xff0c;家长越来越注重孩子的全面发展。从小学就开始为孩子规划竞赛学习&#xff0c;也是很多家长的选择&#xff0c;因为在学习的同时&#xff0c;也可以为以后高考自主招生提前做准备。 但是现在各种类目的竞赛&#xf…

小学奥数思维训练(一)

三年级 4 班组织去秋游&#xff0c;同学们自愿报名。该班一共有 40 名学生&#xff0c;其中 28 名同学报名参加&#xff0c;结果秋游当天去了 36 人&#xff0c;那么肯定有些学生变卦了&#xff08;报名了但是没来&#xff0c;或者没报名却来了&#xff09;&#xff0c;变卦的学…

一个基于ChatGPT的超级读书工具-司马阅(SmartRead)

这时候我强烈推荐一个基于ChatGPT的超级读书工具-司马阅(SmartRead)&#xff0c;它是颠覆我们读书学习方式的一种工具&#xff0c;帮你提取书中重要的知识点&#xff0c;可以以对话聊天的形式按照你的脉络读完它 。可以大大的提升学习工作效率。 先把工具网址放这儿&#xff1…

课程表插件Timetables

课程插件在vue项目中使用 项目中用到之前是用element-table做的,但要求课程一样的要合并单元格,于是啊找了这个插件,分享一下 参考地址: https://github.com/Hzy0913/Timetable 安装: npm install timetables 或者从上面github地址里面下载 Timetables.min.js 参数: 代码 …

Android 课程表

ClassScheduleView 横屏-课程表 预览 资源 名字资源AARclass_schedule_view.aarGiteeClassScheduleViewGitHubClassScheduleView Maven 1.build.grade | setting.grade repositories {...maven { url https://jitpack.io } }2./app/build.grade dependencies {implement…

HTML实现课表(表格运用)

题目要求&#xff1a; 根据表格知识完成下列效果图&#xff1a; 任务提示&#xff1a; 使用 <caption><caption>&#xff0c; <thead></thead> <tbody><tbody> <tfoot></tfoot> 等标签完成。 ps&#xff1a; 其中“课程表”为…

Web:学生课程表表格/用户注册表单

一.学生课程表 1.课程表模样 2.课程表html代码块 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><meta http-equiv"X-UA-Compatible" content"IEedge" /><meta name"viewpo…

当年谷歌为什么退出中国?

《时代》周刊中&#xff0c;百度公司创始人兼CEO李彦宏成为封面人物&#xff0c;成为中国互联网登《时代》的第一人。 而专访中的一段话&#xff0c;却让一段往事再次成为了舆论热议的焦点。专访中&#xff0c;李彦宏表示&#xff0c;谷歌当年退出中国是因为迫于百度给予的市场…

如何处理亿级图片排重(精准排重,相似排重)

图片相似度对比 1、需求 假如有一个图片池&#xff0c;存有1亿图片。给一张目标图片&#xff0c;在图片池中做匹配。 判断一张图片是否在图片池中出现过。&#xff08;完全一样&#xff09;判断有没有相似的出现过。比如两张图相似度90&#xff0c;两张图片是在描述一件事情。 …

pgAdmin的数据导入之CSV

在向数据库批量导入数据时&#xff0c;可以参考此过程 1、对于现有的Excel文件&#xff0c;首先应另存为 .csv文件&#xff0c;记住分割符(逗号分割)&#xff0c;在后边导入用到。 2、用记事本打开保存后的csv文件&#xff0c;以utf-8格式另存为文件。不执行此编码格式&#xf…

ThinkPHP5 关于CSV文件的导入与导出

近期的应项目需求&#xff0c;需要用到数据的导入与导出&#xff0c;因为数据比较多&#xff0c;思来想去使用了CSV格式的文件&#xff0c;结合了网上各位大佬的文章&#xff0c;具体代码如下&#xff1a; 在thinkphp/library/think下新建Csv.php文件&#xff1a; <?php …