当前位置: 首页 > news >正文

基于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程序设计&#xff0c;包括客户端和服务端。 客户端描述&#xff1a;客户端运行开始出现登陆界面。与服务端进行连接&#xff0c;连接后把账号信息发送给服务端&#xff0c;服务端验证后&#xff0c;把确认结果通知客户端。如果通…...

基于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 上传前判断是否开启存储权限&#xff0c;如果不检测直接上传会出现fail的情况 var _this this wx.getSetting({su…...

【Android】使用intent.putExtra()方法在启动Activity时传递数据

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

数据结构与算法编程题35

用按层次顺序遍历二叉树的方法&#xff0c;统计树中具有度为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&#xff0c;之前工作都是用unity&#xff0c;做这类效果用的最多的是一个DoTween的插件&#xff0c;在虚幻中都内置集成了这这种效果制作。 图1.1 UI动画 二、过程 1、首先&#xff0c;在诸如按钮、图像等可交互控件中选中&#xff0c;如…...

【RabbitMQ】RabbitMQ快速入门 通俗易懂 初学者入门

目录 1.初识MQ 1.1.同步和异步通讯 1.1.1.同步通讯 1.1.2.异步通讯 1.2.技术对比&#xff1a; 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

题目&#xff1a;一个数如果恰好等于它的因子之和&#xff0c;这个数就称为"完数"。例如61&#xff0b;2&#xff0b;3.编程找出1000以内的所有完数。 程序分析&#xff1a;请参照&#xff1a;C 练习实例14。 #include<stdio.h> #define N 1000 int main() {…...

Jmeter+Maven+jenkins+eclipse搭建自动化测试平台

背景&#xff1a; 首先用jmeter录制或者书写性能测试的脚本&#xff0c;用maven添加相关依赖&#xff0c;把性能测试的代码提交到github&#xff0c;在jenkins配置git下载性能测试的代码&#xff0c;配置运行脚本和测试报告&#xff0c;配置运行失败自动发邮件通知&#xff0c…...

springboot+jsp+java人才招聘网站4f21r

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

WordPress:构建强大的网站和博客的完美选择

WordPress&#xff1a;构建强大的网站和博客的完美选择 一、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的网络体验

&#x1f337;&#x1f341; 博主猫头虎&#xff08;&#x1f405;&#x1f43e;&#xff09;带您 Go to New World✨&#x1f341; &#x1f984; 博客首页——&#x1f405;&#x1f43e;猫头虎的博客&#x1f390; &#x1f433; 《面试题大全专栏》 &#x1f995; 文章图文…...

【算法】缓存淘汰算法

目录 1.概述2.代码实现2.1.FIFO2.2.LRU2.3.LFU2.4.Clock2.5.Random 3.应用 1.概述 缓存淘汰策略是指在缓存容量有限的情况下&#xff0c;当缓存空间不足时决定哪些缓存项应当被移除的策略。缓存淘汰策略的目标是尽可能地保持缓存命中率高&#xff0c;同时合理地利用有限的缓存…...

接手项目要做的事项

总结&#xff1a;在接手别人的项目时&#xff0c;至少应该自己整理并绘画四个图 1、产品脑图&#xff1a;帮助你理解产品的功能&#xff1b; 2、UML时序图&#xff1a;帮助你源代码的核心技术实现&#xff1b; 3、整体业务泳道图&#xff1a;帮助你从整体上熟悉业务的流程&a…...

【Web】攻防世界Web_php_wrong_nginx_config

这题考察了绕过登录、目录浏览、后门利用 进来先是一个登录框&#xff0c;随便怎么输前端都直接弹窗 禁用js后再输入后登录 查看源码&#xff0c;好家伙&#xff0c;不管输什么都进不去 直接扫目录 访问/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&#xff08;证书&#xff09;: 作用&#xff1a; 证书用于对应用程序和开发者进行身份验证&#xff0c;确保安全性和可…...

MybatisBatchUtils功能介绍

MybatisBatchUtils 是一个 MyBatis 框架的工具类&#xff0c;主要用于简化 MyBatis 中批量操作的代码编写。该工具类封装了 MyBatis 中的批量操作方法&#xff0c;可以方便地进行批量插入、更新和删除等操作。 一般来说&#xff0c;使用 MyBatis 进行批量操作需要先设置 JDBC 驱…...

【JavaWeb】Docker项目部署

引言 之前学习了Linux操作系统的常见命令&#xff0c;在Linux上安装软件&#xff0c;以及如何在Linux上部署一个单体项目&#xff0c;大多数同学都会有相同的感受&#xff0c;那就是麻烦。 核心体现在三点&#xff1a; 命令太多了&#xff0c;记不住 软件安装包名字复杂&…...

在QWebEngineView上实现鼠标、触摸等事件捕获的解决方案

这个问题我看其他博主也写了&#xff0c;要么要会员、要么写的乱七八糟。这里我整理一下&#xff0c;把问题说清楚并且给出代码&#xff0c;拿去用就行&#xff0c;照着葫芦画瓢。 问题 在继承QWebEngineView后&#xff0c;重写mousePressEvent或event函数无法捕获鼠标按下事…...

【Go语言基础【13】】函数、闭包、方法

文章目录 零、概述一、函数基础1、函数基础概念2、参数传递机制3、返回值特性3.1. 多返回值3.2. 命名返回值3.3. 错误处理 二、函数类型与高阶函数1. 函数类型定义2. 高阶函数&#xff08;函数作为参数、返回值&#xff09; 三、匿名函数与闭包1. 匿名函数&#xff08;Lambda函…...

9-Oracle 23 ai Vector Search 特性 知识准备

很多小伙伴是不是参加了 免费认证课程&#xff08;限时至2025/5/15&#xff09; Oracle AI Vector Search 1Z0-184-25考试&#xff0c;都顺利拿到certified了没。 各行各业的AI 大模型的到来&#xff0c;传统的数据库中的SQL还能不能打&#xff0c;结构化和非结构的话数据如何和…...

嵌入式学习之系统编程(九)OSI模型、TCP/IP模型、UDP协议网络相关编程(6.3)

目录 一、网络编程--OSI模型 二、网络编程--TCP/IP模型 三、网络接口 四、UDP网络相关编程及主要函数 ​编辑​编辑 UDP的特征 socke函数 bind函数 recvfrom函数&#xff08;接收函数&#xff09; sendto函数&#xff08;发送函数&#xff09; 五、网络编程之 UDP 用…...

PH热榜 | 2025-06-08

1. Thiings 标语&#xff1a;一套超过1900个免费AI生成的3D图标集合 介绍&#xff1a;Thiings是一个不断扩展的免费AI生成3D图标库&#xff0c;目前已有超过1900个图标。你可以按照主题浏览&#xff0c;生成自己的图标&#xff0c;或者下载整个图标集。所有图标都可以在个人或…...

leetcode_69.x的平方根

题目如下 &#xff1a; 看到题 &#xff0c;我们最原始的想法就是暴力解决: for(long long i 0;i<INT_MAX;i){if(i*ix){return i;}else if((i*i>x)&&((i-1)*(i-1)<x)){return i-1;}}我们直接开始遍历&#xff0c;我们是整数的平方根&#xff0c;所以我们分两…...

计算机系统结构复习-名词解释2

1.定向&#xff1a;在某条指令产生计算结果之前&#xff0c;其他指令并不真正立即需要该计算结果&#xff0c;如果能够将该计算结果从其产生的地方直接送到其他指令中需要它的地方&#xff0c;那么就可以避免停顿。 2.多级存储层次&#xff1a;由若干个采用不同实现技术的存储…...

python读取SQLite表个并生成pdf文件

代码用于创建含50列的SQLite数据库并插入500行随机浮点数据&#xff0c;随后读取数据&#xff0c;通过ReportLab生成横向PDF表格&#xff0c;包含格式化&#xff08;两位小数&#xff09;及表头、网格线等美观样式。 # 导入所需库 import sqlite3 # 用于操作…...

基于谷歌ADK的 智能产品推荐系统(2): 模块功能详解

在我的上一篇博客&#xff1a;基于谷歌ADK的 智能产品推荐系统(1): 功能简介-CSDN博客 中我们介绍了个性化购物 Agent 项目&#xff0c;该项目展示了一个强大的框架&#xff0c;旨在模拟和实现在线购物环境中的智能导购。它不仅仅是一个简单的聊天机器人&#xff0c;更是一个集…...