实现功能:

客户端

1.开启时输入昵称并往服务器端发送带有客户端昵称

2.开启后能随时往服务器端发送聊天内容

3.收到服务器发来的数据时判别是否为自己发送的数据,若不是则输出num编号所指引的内容

4. 当输入quit时退出

服务器

1.接受各个客户端的信息,新用户则将其存入链表中并向各个用户发送有新用户加入的信息

2.当用户输入quit时,删除该用户信息并向各个用户发送该用户退出的信息

3.当收到正常聊天信息时发送给各个用户

代码

客户端

客户端中ip设定为本机的ip地址,通过外部传参传入不同的端口号用以区分不同用户

#include <sys/types.h>
#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include  <arpa/inet.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
#include <stdlib.h>
#define ERR_MSG(msg) do {\fprintf(stderr,"_%d_",__LINE__);\perror(msg);\
}while(0)
#define IP "192.168.31.242"
//#define PORT 8888  // 1024~49151
typedef struct MSG{int num;char name[20];char data[256];
}MSG;int sfd;
struct sockaddr_in cin;
socklen_t addrlen= sizeof(cin);
MSG msg;
char cname[20];
void *shou(void*arg)
{while(1){if(recv(sfd, &msg, sizeof(msg),0) < 0){ERR_MSG("recvfrom");return NULL;}if (strcmp(msg.name,cname)!=0) //判断是否为自己发送的{if(msg.num==3){printf("%s:%s\n",msg.name,msg.data);}if (msg.num==4){printf("%s进入聊天室\n",msg.name);}}}pthread_exit(NULL);}void *fa(void*arg)
{while(1){scanf("%s",msg.data);msg.num=2;strcpy(msg.name,cname);if(sendto(sfd, &msg, sizeof(msg), 0, (struct sockaddr*)&cin, sizeof(cin)) < 0){ERR_MSG("recvfrom");return NULL;}if (strcmp(msg.data,"quit")==0){exit(0);}}pthread_exit(NULL);}//绑定一个广播ip的端口试试int main(int argc, const char *argv[])
{//创建报式套接字sfd =socket(AF_INET,SOCK_DGRAM,0);if (sfd<0){ERR_MSG("socket");return -1;}printf("create socket success\n");int broad =1;if (setsockopt(sfd,SOL_SOCKET,SO_BROADCAST,&broad,sizeof(broad))<0){ERR_MSG("setsockopt");return -1;}//填充地址信息结构体,真实的地址信息结构体与协议族有关//AF_INEt 详见 man 7 ipstruct sockaddr_in sin;sin.sin_family     =AF_INET;sin.sin_port  =htons(8888);//主机字节序转网络字节序的端口号sin.sin_addr.s_addr = inet_addr("192.168.31.255");cin = sin;int port = atoi(argv[1]);struct sockaddr_in bin;bin.sin_family      =AF_INET;bin.sin_port  =htons(port);//主机字节序转网络字节序的端口号bin.sin_addr.s_addr = inet_addr(IP);if(bind(sfd,(struct sockaddr*)&bin,sizeof(bin))==-1){ERR_MSG("bind");return -1;}ssize_t res=0;printf("请输入用户名:");scanf("%s",msg.name);msg.num=1;//num为1时内容为名字strcpy(cname,msg.name);sendto(sfd,&msg,sizeof(msg),0,(struct sockaddr*)&sin, addrlen);msg.num=2; //num为2时内容为聊天内容//将客户端的收发分别写入两个线程,这样就可以同时运行pthread_t tid1,tid2;if (pthread_create(&tid1,NULL,shou,NULL)!=0){ERR_MSG("pthread_create");return -1;}if (pthread_create(&tid2,NULL,fa,NULL)!=0){ERR_MSG("pthread_create");return -1;}pthread_join(tid1,NULL);pthread_join(tid2,NULL);close(sfd);return 0;
}

服务器端

#include <sys/types.h>
#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include  <arpa/inet.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <pthread.h>
#define ERR_MSG(msg) do {\fprintf(stderr,"_%d_",__LINE__);\perror(msg);\
}while(0)typedef struct MSG{int num;char name[20];char data[256];}MSG;MSG msg;
int sfd;
struct sockaddr_in cin;
socklen_t addrlen= sizeof(cin);typedef struct Node{union{int len;struct sockaddr_in nin;}; struct Node * next;
}List;                        //定义一个链表用于存放用户信息int main(int argc, const char *argv[])
{//创建报式套接字sfd =socket(AF_INET,SOCK_DGRAM,0);if (sfd<0){ERR_MSG("socket");return -1;}printf("create socket success\n");int broad =1;if (setsockopt(sfd,SOL_SOCKET,SO_BROADCAST,&broad,sizeof(broad))<0){ERR_MSG("setsockopt");return -1;}MSG msg;//填充地址信息结构体,真实的地址信息结构体与协议族有关//AF_INEt 详见 man 7 ipstruct sockaddr_in sin;sin.sin_family     =AF_INET;sin.sin_port  =htons(8888);//主机字节序转网络字节序的端口号sin.sin_addr.s_addr = inet_addr("192.168.31.255");if (bind(sfd,(struct sockaddr *)&sin,sizeof(sin))<0){ERR_MSG("bind");return -1;}List *l= (List*)malloc(sizeof(List));if (NULL==l){ERR_MSG("malloc");return -1;}l->len=0;l->next=NULL;List * p =NULL;List * q=NULL;ssize_t res=0;while (1){res = recvfrom(sfd,&msg,sizeof(msg),0,(struct sockaddr*)&cin,&addrlen);        if(res == -1){ERR_MSG("recvfrom");return -1;}else if (res>0)//读取成功{if (msg.num==1)//新用户,需a要写入链表{printf("[%s:%d]\n",inet_ntoa(cin.sin_addr),ntohs(cin.sin_port));//使用头插将新用户插入链表中p= (List*)malloc(sizeof(List));if (NULL==p){ERR_MSG("malloc");return -1;}p->next=l->next;p->nin=cin;l->next=p;l->len++;q=l->next;//广播有新的用户进入聊天msg.num=4;//防止自己收到后继续输出while(q!=NULL){if(sendto(sfd,&msg,sizeof(msg),0,(struct sockaddr*)&q->nin,sizeof(q->nin))<0){ERR_MSG("sendto");return -1;}q=q->next;}}else if(msg.num==2)//老用户{printf("[%s:%d]\n",inet_ntoa(cin.sin_addr),ntohs(cin.sin_port));if (strcmp(msg.data,"quit")==0)//用户退出,需要广播退出信息并将其在链表中删除{msg.num=3;strcpy(msg.data,"已退出");q=l->next;while(q!=NULL){if(sendto(sfd,&msg,sizeof(msg),0,(struct sockaddr*)&q->nin,sizeof(q->nin))<0){ERR_MSG("sendto");return -1;}q=q->next;}p=l;while (p->next!=NULL){if (p->next->nin.sin_port == cin.sin_port){q=p->next->next;free(p->next);p->next=q;break;}p=p->next;}//将该用户在链表中删除}else{//正常聊天广播收到的内容msg.num =3;//防止自己收到后继续输出q=l->next;while(q!=NULL){if(sendto(sfd,&msg,sizeof(msg),0,(struct sockaddr*)&q->nin,sizeof(q->nin))<0){ERR_MSG("sendto");return -1;}q=q->next;}}}}}close(sfd);return 0;
}

运行测试 :

成功完成预计功能。

使用UDP协议构建简易局域网内聊天室相关推荐

  1. python实现简易聊天需要登录_python编写简易聊天室实现局域网内聊天功能

    本文实例为大家分享了python实现局域网内聊天功能的具体代码,供大家参考,具体内容如下 功能: 可以向局域网内开启接收信息功能的ip进行发送信息,我们可以写两段端口不同的代码来实现在一台电脑上与自己 ...

  2. python语言视频-Python语言之Python3 实现简易局域网视频聊天工具

    本文主要向大家介绍了Python语言之Python3 实现简易局域网视频聊天工具,通过具体的内容向大家展示,希望对大家学习Python语言有所帮助. 操作系统为 Ubuntu 16.04,OpenCV ...

  3. 网络编程套接字(上篇)UDP实现简易多人聊天室

    目录 背景知识 主机间通信本质 socket 端口号特点: 为什么不用进程pid? 网络字节序 socket编程接口API sockaddr结构 ​编辑 简单UDP网络程序 了解UDP协议 简易多人聊 ...

  4. Python3 实现简易局域网视频聊天工具

    Python3 实现简易局域网视频聊天工具 1.环境 操作系统为 Ubuntu 16.04 python 3.5 opencv-python 3.4.1.15 numpy 1.14.5 PyAudio ...

  5. 利用TCP/UDP 协议制作一个飞秋聊天工具

    视频操作演示: 利用TCP/UDP 协议制作一个飞秋聊天工具演示视频 int udp_broadcast(char const*argv[]) {//1.创建对象udp_socket = socket ...

  6. python实现简易聊天需要登录博客园zip下载_Python基于Socket实现简易多人聊天室的示例代码...

    前言 套接字(Sockets)是双向通信信道的端点. 套接字可以在一个进程内,在同一机器上的进程之间,或者在不同主机的进程之间进行通信,主机可以是任何一台有连接互联网的机器. 套接字可以通过多种不同的 ...

  7. 基于TCP协议的mfc多人聊天室

    基于TCP协议的MFC多人聊天室 简易的mfc聊天室思路实现 前言 一.socket通信 二.效果展示 三.代码实现 1.ClientSocket.cpp 客户端套接字 2.ServerSocket. ...

  8. JAVA网络编程NIO实现简易多人聊天室

    BIO模型 BIO即blocking IO,顾名思义是一种阻塞模型.当没有客户端连接时,服务端会一直阻塞,当有客户端新建连接时,服务端会新开一个线程去响应(不用多线程的话服务端同一时刻最多只能接收一个 ...

  9. Java Socket实现简易多人聊天室传输聊天内容或文件

    Java Socket实现简易多人聊天室传输聊天内容或文件 Java小练手项目:用Java Socket实现多人聊天室,聊天室功能包括传输聊天内容或者文件.相比于其它的聊天室,增加了传输文件的功能供参 ...

最新文章

  1. Win10控制桌面图标显示
  2. DevOps简单介绍
  3. ATL的GUI程序设计(前言)
  4. caffe提取每一层中的特征,在matlab或python查看
  5. 深度学习基础(二)—— 从多层感知机(MLP)到卷积神经网络(CNN)
  6. 感谢大家的热情与温暖
  7. 多个客户端共用同一条拉起链接 ,如何配置 Universal Link iOS App
  8. C++11模板友元语法
  9. 经验分享:我是如何在网店无货源情况下快速出单?
  10. d3开发Svg编辑器
  11. 批处理批量卸载微软补丁
  12. 用友u8怎么导出凭证_老师,用友U8里的凭证如何导出(导出有借贷方向的)?...
  13. 微信公众号首次关注自动回复图文信息
  14. 怎样用python制表_用Python绘图和制表(附泰坦尼克号案例)
  15. MPC+HSM造就了安全的数字托管人
  16. 【算法】求解钱币兑换问题
  17. 郭炜:CTO、技术VP、技术总监、首席架构师的区别?
  18. TypeError: e[h] is not a function
  19. 若依框架---分页功能
  20. Python 验证Mac地址

热门文章

  1. qboost怎么设置_qboost怎么用 教你设置最好方法,但是很多人下载过来不
  2. ZIGBEE通讯-10.ZigBee协议栈的无线点灯
  3. 张量基础学习(一 概念,求和指标,符号)
  4. 一、jar包部署成win服务。
  5. 开发新浪微博android客户端
  6. 计算机游戏的书推荐,十大耐玩的电脑单机游戏排行,经典单机游戏推荐
  7. 怎样下载ps2020软件和安装,ps2021安装包怎么下载
  8. Windows窗口相关的一些概念解释
  9. VSCode 插件安装:中文(简体)语言包(附带:不生效解决方案)
  10. mhdd应用详解-入门篇(图文教程)