基于UDP网络聊天室OICQ
Linux系统 + Gcc + Gdb + makefile
实现局域网OICQ程序设计,包括客户端和服务端。
客户端描述:客户端运行开始出现登陆界面。与服务端进行连接,连接后把账号信息发送给服务端,服务端验证后,把确认结果通知客户端。如果通过验证,客户端从服务端接收其他在线客户端信息并把这些客户信息显示给用户。用户可以选择客户并与之进行信息交流。即发送消息和接受消息。并把结果显示给用户。
服务端功能描述:服务端启动后,等待客户端连接。接受客户端发送过来的账号信息。进行验证。并把验证的结果返回给客户端。如果验证通过,记录客户端的信息。并把该客户端的记录的信息发送给其他的客户端,也把其他的在线用户发送给该用户,实现整个网络内的在线客户信息的同步。接受客户端的断开连接的请求。服务端断开连接,删除记录并把结果发送给其他的客户端。
Sock编程
根据配置文件信息启动服务端程序,监听端口,等待客户端连接。完成客户端于服务端简单的tcp连接。使用I/O复用机制完成客户端与服务端之间的一对多的连接。服务端记录每个客户端的基本信息:每个客户端的IP、端口等基本信息。使用链表记录保存这些信息。
相关代码参考
客户端:
#include <myhead.h>typedef struct
{char type;char name[20];char text[128];
}msg_t;
//定义传送消息的结构体
int main(int argc, const char *argv[])
{if(argc != 3){printf("请输入服务器IP和端口号!\n");return -1;}
//提醒输入IP和端口号int cfd = socket(AF_INET,SOCK_DGRAM,0);if(cfd == -1){perror("socket error");return -1;}
//创建套接字用于通信msg_t msg;char name[20] = "";printf("请输入用户名>>");scanf("%s",msg.name);getchar();
//输入名字struct sockaddr_in sin;sin.sin_family = AF_INET;sin.sin_port = htons(atoi(argv[2]));sin.sin_addr.s_addr = inet_addr(argv[1]);
//定义发送的服务器结构体char buf[129] = "";char rbuf[128] = "";bzero(buf,sizeof(buf));msg.type = 'L';sendto(cfd,&msg,sizeof(msg),0,(struct sockaddr*)&sin,sizeof(sin));
//发送登录信息结构体struct pollfd fds[2];fds[0].fd = 0;fds[0].events = POLLIN;fds[1].fd = cfd;fds[1].events = POLLIN;int res = 0;
//用poll函数多路复用while(1){res = poll(fds,2,-1);if(res == -1){perror("poll error");return -1;}else if(res == 0){printf("time out\n");return -1;}bzero(buf,sizeof(buf));bzero(rbuf,sizeof(rbuf));if(fds[1].revents == POLLIN){recvfrom(cfd,rbuf,sizeof(rbuf),0,NULL,NULL);printf("%s\n",rbuf);}if(fds[0].revents == POLLIN){fgets(msg.text,sizeof(msg.text),stdin);msg.text[strlen(msg.text)-1]='\0';if(strcmp(msg.text,"quit")==0){msg.type = 'Q';sendto(cfd,&msg,sizeof(msg),0,(struct sockaddr*)&sin,sizeof(sin));goto A;}msg.type = 'C';sendto(cfd,&msg,sizeof(msg),0,(struct sockaddr*)&sin,sizeof(sin));}}
A:close(cfd);return 0;
}
服务端:
#include <myhead.h>
typedef struct group
{char type;char name[20];char text[128];
}msg_t;
//创建信息结构体
typedef struct Node
{int PORT;struct Node* next;
}*Linklist;
//创建链表数据域的结构体
Linklist create_node()
{Linklist s=(Linklist)malloc(sizeof(struct Node));if(NULL == s)return NULL;s->PORT =0;s->next =NULL;return s;
}
//创建链表节点
Linklist insert_rear(Linklist head,int element)
{Linklist s=create_node();s->PORT=element;if(NULL == head){head = s;return head;}Linklist p = head;while(p->next != NULL){p=p->next;}p->next = s;return head;
}
//链表的头删int lenth(Linklist head)
{if(head == NULL)return 0;int count=0;Linklist p=head;while(p!=NULL){count++;p=p->next;}free(p);p=NULL;return count;
}
//链表求长度
int find_element(Linklist head,int element)
{Linklist p=head;for(int i=0;i<lenth(head);i++){if(p->PORT == element)return i;p=p->next;}
}
//链表的按照元素查找
Linklist link_del_head(Linklist head)
{if(head->next == NULL){free(head);head=NULL;return head;}Linklist del=head->next;head->PORT=del->PORT;head->next=del->next;free(del);del=NULL;return head;
}
//链表的头删
Linklist link_del_rear(Linklist head)
{if(head->next == NULL){free(head);head = NULL;return head;}Linklist del=head;while(del->next->next!=NULL){del=del->next;}free(del->next);del->next=NULL;return head;
}
//链表的尾删
Linklist link_del_pos(Linklist head,int pos)
{if(pos == lenth(head)-1){head = link_del_rear(head);return head;}else if(pos == 0){head = link_del_head(head);return head;}else{Linklist p=head;for(int i=0;i<pos-1;i++){p=p->next;}Linklist r=p->next;p->next=r->next;free(r);r=NULL;return head;}
}
//链表的按照信息删除
Linklist del(Linklist head,int element)
{if(head ==NULL)return head;int pos = find_element(head,element);head = link_del_pos(head,pos);return head;
}
//链表按照位置删除
int main(int argc, const char *argv[])
{if(argc != 3){printf("请输入服务器IP和端口号!\n");return -1;}int sfd = socket(AF_INET,SOCK_DGRAM,0);if(sfd == -1){perror("socket error");return -1;}//创建套接字用于通信struct sockaddr_in sin;sin.sin_family = AF_INET;sin.sin_port = htons(atoi(argv[2]));sin.sin_addr.s_addr = inet_addr(argv[1]);//定义服务器的信息结构体if(bind(sfd,(struct sockaddr*)&sin,sizeof(sin))==-1){perror("bind error");return -1;}printf("bind success\n");struct sockaddr_in cin;cin.sin_family = AF_INET;socklen_t socklen = sizeof(cin);Linklist Usr_PORT=NULL;msg_t usr;char buf[149] = "";char rbuf[130] = "";//根据poll函数IO多路复用struct pollfd fds[2];fds[0].fd = 0;fds[0].events = POLLIN;fds[1].fd = sfd;fds[1].events = POLLIN;int res = 0; //接收select的返回值while(1){res = poll(fds,2,-1);if(res == -1){perror("poll error");return -1;}else if(res == 0){printf("time out");return -1;}bzero(buf,sizeof(buf));if(fds[0].revents == POLLIN){strcpy(buf,"SYSMSG:");fgets(buf+7,sizeof(buf)-7,stdin);buf[strlen(buf)-1] = '\0';Linklist p = Usr_PORT;while(p!= NULL){cin.sin_port = htons(p->PORT);sendto(sfd,buf,sizeof(buf),0,(struct sockaddr*)&cin,sizeof(cin));p=p->next;}}if(fds[1].revents == POLLIN){recvfrom(sfd,&usr,sizeof(usr),0,(struct sockaddr*)&cin,&socklen);if(usr.type == 'L'){Usr_PORT = insert_rear(Usr_PORT,ntohs(cin.sin_port));printf("[%s:%d]已经上线\n",usr.name,ntohs(cin.sin_port));sprintf(buf,"%s已经上线",usr.name);printf("buf = %s\n",buf);Linklist p = Usr_PORT;while(p->next!= NULL){cin.sin_port = htons(p->PORT);sendto(sfd,buf,sizeof(buf),0,(struct sockaddr*)&cin,sizeof(cin));p=p->next;}}else if(usr.type == 'C'){sprintf(buf,"%s:%s",usr.name,usr.text);Linklist p = Usr_PORT;int NONE=ntohs(cin.sin_port);while(p!= NULL){if(NONE!=p->PORT){cin.sin_port = htons(p->PORT);sendto(sfd,buf,sizeof(buf),0,(struct sockaddr*)&(cin),sizeof(cin));}p=p->next;}}else if(usr.type == 'Q'){sprintf(buf,"%sdownline",usr.name);printf("[%s:%d]downline\n",usr.name,ntohs(cin.sin_port));Usr_PORT = del(Usr_PORT,ntohs(cin.sin_port));Linklist p = Usr_PORT;while(p!= NULL){cin.sin_port = htons(p->PORT);sendto(sfd,buf,sizeof(buf),0,(struct sockaddr*)&cin,sizeof(cin));p=p->next;}}}}close(sfd);return 0;
}
相关文章:
基于UDP网络聊天室OICQ
Linux系统 Gcc Gdb makefile 实现局域网OICQ程序设计,包括客户端和服务端。 客户端描述:客户端运行开始出现登陆界面。与服务端进行连接,连接后把账号信息发送给服务端,服务端验证后,把确认结果通知客户端。如果通…...

基于STC12C5A60S2系列1T 8051单片机的液晶显示器LCD1602显示整数、小数应用
基于STC12C5A60S2系列1T 8051单片机的液晶显示器LCD1602显示整数、小数应用 STC12C5A60S2系列1T 8051单片机管脚图STC12C5A60S2系列1T 8051单片机I/O口各种不同工作模式及配置STC12C5A60S2系列1T 8051单片机I/O口各种不同工作模式介绍液晶显示器LCD1602简单介绍IIC通信简单介绍…...
【微信小程序】保存多张图片到本地相册 wx.saveImageToPhotosAlbum
这里写目录标题 微信小程序检测是否有存储权限wx.getSetting 图片上传从HTML中提取img标签的src属性多图片下载 微信小程序检测是否有存储权限 wx.getSetting 上传前判断是否开启存储权限,如果不检测直接上传会出现fail的情况 var _this this wx.getSetting({su…...

【Android】使用intent.putExtra()方法在启动Activity时传递数据
食用方法 在Android中,你可以使用Intent对象来在启动Activity时传递数据。以下是一个示例,展示了如何在startActivity时传递数据到被启动的Activity: 在启动Activity的地方,创建一个Intent对象,并使用putExtra()方法…...

数据结构与算法编程题35
用按层次顺序遍历二叉树的方法,统计树中具有度为1的结点数目。 #define _CRT_SECURE_NO_WARNINGS#include <iostream> using namespace std;typedef char ElemType; #define ERROR 0 #define OK 1 #define Maxsize 100 #define STR_SIZE 1024typedef struct B…...
每日一题 - 231201 - Divisibility by Eight
Divisibility by Eight TAG - 整除特性、枚举 整除特性、枚举 整除特性、枚举时间复杂度 - O ( N 3 ) O(N^3) O(N3) // #include<bits/stdc.h> using namespace std; // #define int long long void solve() {string s;cin>>s;for( int i0;i<s.size();i )if(…...

虚幻学习笔记1—给UI添加动画
一、前言 本文所使用的虚幻版本为5.3.2,之前工作都是用unity,做这类效果用的最多的是一个DoTween的插件,在虚幻中都内置集成了这这种效果制作。 图1.1 UI动画 二、过程 1、首先,在诸如按钮、图像等可交互控件中选中,如…...

【RabbitMQ】RabbitMQ快速入门 通俗易懂 初学者入门
目录 1.初识MQ 1.1.同步和异步通讯 1.1.1.同步通讯 1.1.2.异步通讯 1.2.技术对比: 2.快速入门 2.1.安装RabbitMQ 2.2.RabbitMQ消息模型 2.3.导入Demo工程 2.4.入门案例 2.4.1.publisher实现 2.4.2.consumer实现 2.5.总结 3.SpringAMQP 3.1.Basic Que…...

JAVEE初阶 多线程基础(四)
线程安全 一.线程安全存在的问题二.锁三.关于锁的理解四.关于锁操作混淆的理解4.1两个线程是否对同一对象加锁 一.线程安全存在的问题 为什么这里的count不是一百万呢?这就是线程所存在的不安全的问题,由于线程是抢占式执行,同时执行count,操作本质是三个指令 1.load 读取内存…...
【C 语言经典100例】C 练习实例19
题目:一个数如果恰好等于它的因子之和,这个数就称为"完数"。例如61+2+3.编程找出1000以内的所有完数。 程序分析:请参照:C 练习实例14。 #include<stdio.h> #define N 1000 int main() {…...

Jmeter+Maven+jenkins+eclipse搭建自动化测试平台
背景: 首先用jmeter录制或者书写性能测试的脚本,用maven添加相关依赖,把性能测试的代码提交到github,在jenkins配置git下载性能测试的代码,配置运行脚本和测试报告,配置运行失败自动发邮件通知,…...

springboot+jsp+java人才招聘网站4f21r
本基于springboot的人才招聘网站主要满足3种类型用户的需求,这3种类型用户分别为求职者、企业和管理员,他们分别实现的功能如下。 (1)求职者进入网站后可查看职位信息、企业信息以及职位新闻等,注册登录后可实现申请职…...

WordPress:构建强大的网站和博客的完美选择
WordPress:构建强大的网站和博客的完美选择 一、WordPress 简介1.1 WordPress 介绍1.2 WordPress 优势 二、部署LNMP环境2.1 前提条件2.2 关闭防火墙和SELinux2.3 安装Nginx2.4 安装MySQL2.5 安装PHP2.6 配置Nginx2.7 配置MySQL2.8 配置PHP2.9 测试访问LNMP平台 三、…...

2021年8月18日 Go生态洞察:整合Go的网络体验
🌷🍁 博主猫头虎(🐅🐾)带您 Go to New World✨🍁 🦄 博客首页——🐅🐾猫头虎的博客🎐 🐳 《面试题大全专栏》 🦕 文章图文…...

【算法】缓存淘汰算法
目录 1.概述2.代码实现2.1.FIFO2.2.LRU2.3.LFU2.4.Clock2.5.Random 3.应用 1.概述 缓存淘汰策略是指在缓存容量有限的情况下,当缓存空间不足时决定哪些缓存项应当被移除的策略。缓存淘汰策略的目标是尽可能地保持缓存命中率高,同时合理地利用有限的缓存…...
接手项目要做的事项
总结:在接手别人的项目时,至少应该自己整理并绘画四个图 1、产品脑图:帮助你理解产品的功能; 2、UML时序图:帮助你源代码的核心技术实现; 3、整体业务泳道图:帮助你从整体上熟悉业务的流程&a…...

【Web】攻防世界Web_php_wrong_nginx_config
这题考察了绕过登录、目录浏览、后门利用 进来先是一个登录框,随便怎么输前端都直接弹窗 禁用js后再输入后登录 查看源码,好家伙,不管输什么都进不去 直接扫目录 访问/robots.txt 访问/hint.php 访问/Hack.php 抓包看一下 cookie里isLogin0…...
Flume采集Kafka并把数据sink到OSS
安装环境 Java环境, 略 (Flume依赖Java)Flume下载, 略Scala环境, 略 (Kafka依赖Scala)Kafak下载, 略Hadoop下载, 略 (不需要启动, 写OSS依赖) 配置Hadoop 下载JindoSDK(连接OSS依赖), 下载地址Github 解压后配置环境变量 export JINDOSDK_HOME/usr/lib/jindosdk-x.x.x expo…...

flutter,uni-app开发调试ios
一、申请ios开发者账号 二、ios开发者配置 ios 开发者需要配置的地方 https://developer.apple.com/account/resources/certificates/list Certificates(证书): 作用: 证书用于对应用程序和开发者进行身份验证,确保安全性和可…...
MybatisBatchUtils功能介绍
MybatisBatchUtils 是一个 MyBatis 框架的工具类,主要用于简化 MyBatis 中批量操作的代码编写。该工具类封装了 MyBatis 中的批量操作方法,可以方便地进行批量插入、更新和删除等操作。 一般来说,使用 MyBatis 进行批量操作需要先设置 JDBC 驱…...
镜像里切换为普通用户
如果你登录远程虚拟机默认就是 root 用户,但你不希望用 root 权限运行 ns-3(这是对的,ns3 工具会拒绝 root),你可以按以下方法创建一个 非 root 用户账号 并切换到它运行 ns-3。 一次性解决方案:创建非 roo…...
【android bluetooth 框架分析 04】【bt-framework 层详解 1】【BluetoothProperties介绍】
1. BluetoothProperties介绍 libsysprop/srcs/android/sysprop/BluetoothProperties.sysprop BluetoothProperties.sysprop 是 Android AOSP 中的一种 系统属性定义文件(System Property Definition File),用于声明和管理 Bluetooth 模块相…...

PL0语法,分析器实现!
简介 PL/0 是一种简单的编程语言,通常用于教学编译原理。它的语法结构清晰,功能包括常量定义、变量声明、过程(子程序)定义以及基本的控制结构(如条件语句和循环语句)。 PL/0 语法规范 PL/0 是一种教学用的小型编程语言,由 Niklaus Wirth 设计,用于展示编译原理的核…...

Map相关知识
数据结构 二叉树 二叉树,顾名思义,每个节点最多有两个“叉”,也就是两个子节点,分别是左子 节点和右子节点。不过,二叉树并不要求每个节点都有两个子节点,有的节点只 有左子节点,有的节点只有…...
管理学院权限管理系统开发总结
文章目录 🎓 管理学院权限管理系统开发总结 - 现代化Web应用实践之路📝 项目概述🏗️ 技术架构设计后端技术栈前端技术栈 💡 核心功能特性1. 用户管理模块2. 权限管理系统3. 统计报表功能4. 用户体验优化 🗄️ 数据库设…...
《C++ 模板》
目录 函数模板 类模板 非类型模板参数 模板特化 函数模板特化 类模板的特化 模板,就像一个模具,里面可以将不同类型的材料做成一个形状,其分为函数模板和类模板。 函数模板 函数模板可以简化函数重载的代码。格式:templa…...
0x-3-Oracle 23 ai-sqlcl 25.1 集成安装-配置和优化
是不是受够了安装了oracle database之后sqlplus的简陋,无法删除无法上下翻页的苦恼。 可以安装readline和rlwrap插件的话,配置.bahs_profile后也能解决上下翻页这些,但是很多生产环境无法安装rpm包。 oracle提供了sqlcl免费许可,…...
虚幻基础:角色旋转
能帮到你的话,就给个赞吧 😘 文章目录 移动组件使用控制器所需旋转:组件 使用 控制器旋转将旋转朝向运动:组件 使用 移动方向旋转 控制器旋转和移动旋转 缺点移动旋转:必须移动才能旋转,不移动不旋转控制器…...
Python第七周作业
Python第七周作业 文章目录 Python第七周作业 1.使用open以只读模式打开文件data.txt,并逐行打印内容 2.使用pathlib模块获取当前脚本的绝对路径,并创建logs目录(若不存在) 3.递归遍历目录data,输出所有.csv文件的路径…...
RLHF vs RLVR:对齐学习中的两种强化方式详解
在语言模型对齐(alignment)中,强化学习(RL)是一种重要的策略。而其中两种典型形式——RLHF(Reinforcement Learning with Human Feedback) 与 RLVR(Reinforcement Learning with Ver…...