当前位置:网站首页>Group chat room based on UDP
Group chat room based on UDP
2022-07-24 01:00:00 【lhb2998658795】
1.UDP The function of group chat
There are new users logging in , Other online users can receive login information
User group chat , Other online users can receive group chat information
Some users quit , Other online users can receive the exit message
The server can send system information
2 Write the process of the project
Draw flow chart
Write the framework according to the flow chart
One function, one function
3 flow chart

4 Code implementation
4.1 The header file
#ifndef __MYHEAD_H__
#define __MYHEAD_H__
#include <head.h>
#define N 512
// The structure of chat operation
typedef struct _MSG{
char ch;// be used for 'l' Chat ,'q' sign out ,' Sign in d'
char name[128];// Save your name
char text[N];// Save chat content
}msg_t;
// The structure used to store each user's information
typedef struct _Jilu{
struct sockaddr_in addr;
struct _Jilu *next;
}jilu_t;
int create_head(jilu_t **head);
int input_addr(jilu_t *head,msg_t msg,int sockfd,struct sockaddr_in clientaddr,socklen_t clientaddr_len);
int wx_addr(jilu_t *head,msg_t msg,int sockfd,struct sockaddr_in clientaddr,socklen_t clientaddr_len);
int tuichu_addr(jilu_t *head,msg_t msg,int sockfd,struct sockaddr_in clientaddr,socklen_t clientaddr_len);
#endif4.2 function
#include "myhead.h"
// Create a single chain header
int create_head(jilu_t **head)
{
if(head==NULL){
printf(" Transmission error , Please check \n");
return -1;
}
(*head)=(jilu_t *)malloc(sizeof(jilu_t));
(*head)->next=NULL;
return 0;
}
// Record the information of the logged in user
int input_addr(jilu_t *head,msg_t msg,int sockfd,struct sockaddr_in clientaddr,socklen_t clientaddr_len)
{
if(head==NULL){
printf(" Transmission error , Please check \n");
return -1;
}
// Send the login information of this user to everyone
snprintf(msg.text,sizeof(msg.text),"[%s]%s",msg.name," Log on to the ");
// This is used to record the address of the header
jilu_t *jilu_head=head;
while(jilu_head->next!=NULL){
jilu_head=jilu_head->next;
if(sendto(sockfd,&msg,sizeof(msg),0,(struct sockaddr*)&jilu_head->addr,clientaddr_len)==-1){
ERRLOG(" Failed to send the user login information to everyone ");
}
}
// Create a new node , And put the new user information into the new order list
jilu_t *temp=NULL;
create_head(&temp);
temp->addr=clientaddr;
// Insert the user information into the linked list with header insertion
temp->next=head->next;
head->next=temp;
return 0;
}
int wx_addr(jilu_t *head,msg_t msg,int sockfd,struct sockaddr_in clientaddr,socklen_t clientaddr_len)
{
if(head==NULL){
printf(" Transmission error , Please check \n");
return -1;
}
// Send the received message to everyone except yourself
jilu_t *jilu_head=head;
while(jilu_head->next!=NULL){
jilu_head=jilu_head->next;
if(0!=memcmp(&(jilu_head->addr),&clientaddr,sizeof(clientaddr))){
if(sendto(sockfd,&msg,sizeof(msg),0,(struct sockaddr*)&jilu_head->addr,clientaddr_len)==-1){
ERRLOG(" Failed to send the chat content to everyone ");
}
}
}
return 0;
}
int tuichu_addr(jilu_t *head,msg_t msg,int sockfd,struct sockaddr_in clientaddr,socklen_t clientaddr_len)
{
if(head==NULL){
printf(" Transmission error , Please check \n");
return -1;
}
snprintf(msg.text,sizeof(msg.text),"%s%s",msg.name," Log out ");
jilu_t *jilu_head=head;
jilu_t *pdel=NULL;
while(jilu_head->next!=NULL){
if(0==memcmp(&(jilu_head->next->addr),&clientaddr,sizeof(clientaddr))){
pdel=jilu_head->next;
jilu_head->next=pdel->next;
free(pdel);
pdel=NULL;
}else{
jilu_head=jilu_head->next;
if(sendto(sockfd,&msg,sizeof(msg),0,(struct sockaddr*)&jilu_head->addr,clientaddr_len)==-1){
ERRLOG(" Tell everyone about this exit message and fail ");
}
}
}
return 0;
}4.3 The server
#include "myhead.h"
int main(int argc, char const *argv[])
{
int sockfd=0;
pid_t pid=0;
msg_t msg;// Used for various operations
msg_t faso;// Used to send system messages
if((sockfd=socket(AF_INET,SOCK_DGRAM,0))==-1){
ERRLOG(" Failed to create server socket ");
}
// Put the network information structure into the server
struct sockaddr_in serveraddr;
memset(&serveraddr,0,sizeof(serveraddr));
serveraddr.sin_family=AF_INET;
serveraddr.sin_port=htons(atoi(argv[2]));
serveraddr.sin_addr.s_addr=inet_addr(argv[1]);
socklen_t serveraddr_len=sizeof(serveraddr);
// Bind the socket to the network information structure
if(bind(sockfd,(struct sockaddr*)&serveraddr,serveraddr_len)==-1){
ERRLOG(" Binding socket to network information structure failed ");
}
// Create a new network information structure to store client information
struct sockaddr_in clientaddr;
clientaddr.sin_family=AF_INET;
socklen_t clientaddr_len=sizeof(clientaddr);
// Create a process
pid=fork();
if(pid==-1){
ERRLOG(" Server creation process failed ");
}else if(pid==0){
// Create a single list to save the network information structure
jilu_t *head;
create_head(&head);
memset(&msg,0,sizeof(msg));
while(1){
if(recvfrom(sockfd,&msg,sizeof(msg),0,(struct sockaddr*)&clientaddr,&clientaddr_len)==-1){
ERRLOG(" Failed to accept the information from the client ");
}
switch(msg.ch){
case 'd':// login information
input_addr(head,msg,sockfd,clientaddr,clientaddr_len);
//head->next=NULL; // This is for testing
break;
case 'l':// Chat messages
wx_addr(head,msg,sockfd,clientaddr,clientaddr_len);
break;
case 'q':// Exit message
tuichu_addr(head,msg,sockfd,clientaddr,clientaddr_len);
break;
}
}
}else{
while(1){
// Send system messages
memset(&faso,0,sizeof(faso));
fgets(faso.text,sizeof(faso.text),stdin);
faso.text[strlen(faso.text)-1]='\0';
faso.ch='l';
sprintf(faso.name,"%s"," System message ");
if(sendto(sockfd,&faso,sizeof(faso),0,(struct sockaddr*)&serveraddr,serveraddr_len)==-1){
ERRLOG(" Sending system message failed ");
}
}
}
return 0;
}
4.4 client
#include "myhead.h"
int main(int argc, char const *argv[])
{
// Judge whether the input is correct
if(argc!=3){
printf(" Input format error ,./a.out ip port\n");
exit(EXIT_SUCCESS);
}
int sockfd=0;
pid_t pid=0;
msg_t msg;// Create and send user information
if((sockfd=socket(AF_INET,SOCK_DGRAM,0))==-1){
ERRLOG(" Failed to create client socket ");
}
// Bind the client network information structure
struct sockaddr_in clientaddr;
memset(&clientaddr,0,sizeof(clientaddr));
clientaddr.sin_family=AF_INET;
clientaddr.sin_port=htons(atoi(argv[2]));
clientaddr.sin_addr.s_addr=inet_addr(argv[1]);
socklen_t clientaddr_len=sizeof(clientaddr);
// Enter the user's name to log in
msg.ch='d';
printf(" Please enter the name you use to sign in ");
fgets(msg.name,sizeof(msg.name),stdin);
msg.name[strlen(msg.name)-1]='\0';
// Send the operation that the user has logged in to the server
if(sendto(sockfd,&msg,sizeof(msg),0,(struct sockaddr*)&clientaddr,clientaddr_len)==-1){
ERRLOG(" The login information sent by the client to the server failed ");
}
// Create a process , Subprocesses are used to accept , The parent process is used to send
pid=fork();
if(pid==-1){
ERRLOG(" Client creation process failed ");
}else if(pid==0){
// Used to receive messages from the server
while(1){
memset(&msg,0,sizeof(msg));
if(recvfrom(sockfd,&msg,sizeof(msg),0,NULL,NULL)==-1){
ERRLOG(" The message sent by the receiving server is wrong ");
}
printf("[%s]>>(%s)\n",msg.name,msg.text);
}
}else{
// Write the content to be chatted
while(1){
memset(msg.text,0,sizeof(msg.text));
fgets(msg.text,sizeof(msg.text),stdin);
msg.text[strlen(msg.text)-1]='\0';
if(strncmp("quit",msg.text,5)==0){
msg.ch='q';
}else{
msg.ch='l';
}
// Send the written content to the server
if(sendto(sockfd,&msg,sizeof(msg),0,(struct sockaddr*)&clientaddr,clientaddr_len)==-1){
ERRLOG(" Failed to send chat content to the server ");
}
// When the stop is recognized , Close the process
if(strncmp("quit",msg.text,5)==0){
kill(pid,SIGKILL);
close(sockfd);
exit(EXIT_SUCCESS);
}
}
}
return 0;
}
边栏推荐
- Hcia-01 initial understanding of the Internet
- Introduction to QT (2.1 the first procedure for the beginning of QT)
- JS determines whether the element scrolls to the top
- Notes: middle order traversal of binary trees (three solutions - recursion, iteration, Morris)
- Create a self signed certificate to digitally sign exe files
- Sword finger offer frog jumps stairs
- Linkerd service grid survey notes
- Deep understanding of collaborative process
- Socket basic knowledge and various usage scenarios
- Use of crawler request library 2
猜你喜欢

Database connection pool & dbutils

如何使用 SAP Intelligent Robotic Process Automation 自动操作 Excel

创建自签名证书, 对exe文件进行数字签名

docker mysql

工作3年的测试员跳槽后工资是原来的2倍,秘诀原来是......

LVS load balancing scheduling principle and configuration method

T-seda code

GLIB-CRITICAL g_ file_ test:assertion ‘filename != null‘ failed

The way to access global variables in multi-source file mode (extern usage)

How to use SAP intelligent robotic process automation to automate Excel
随机推荐
Notes to Chapter 2 of kubernetes in action
落枕如何快速缓解
Solve the problem that MySQL inserts Chinese garbled code into the table
Sword finger offer frog jumps stairs
Bean validation usage article ----05
Case error of MySQL branch statement
About redis: there is still a risk of data loss after redis sets data persistence
Bean Validation自定义容器验证篇----06
Solve the error: uncaught (in promise) navigationduplicated: avoided redundant navigation to current location:“
mysql 分支语句case报错
Basic use of crawler requests module
Tutorial on principles and applications of database system (051) -- MySQL query (XIII): using queries in DML statements
Xilinx FPGA one way clock input two PLLs
Source code installation and use of APIs IX
freemarker
[QNX hypervisor 2.2 user manual]9.1 configuration variables
ACL——net
Tutorial on principles and applications of database system (045) -- MySQL query (VII): aggregate function
[untitled]
Image processing: Generation 3 × Window of 3