最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C語言利用UDP實現(xiàn)群聊聊天室的示例代碼

 更新時間:2022年08月18日 16:00:30   作者:lhb2998658795  
UDP是一個輕量級、不可靠、面向數(shù)據(jù)報的、無連接的傳輸層協(xié)議,多用于可靠性要求不嚴(yán)格,不是非常重要的傳輸,如直播、視頻會議等等。本文將利用UDP實現(xiàn)簡單的群聊聊天室,感興趣的可以了解一下

1.UDP群聊的功能

有新用戶登錄,其他在線的用戶可以收到登錄信息

有用戶群聊,其他在線的用戶可以收到群聊信息

有用戶退出,其他在線的用戶可以收到退出信息

服務(wù)器可以發(fā)送系統(tǒng)信息

2.寫項目的流程

畫流程圖

根據(jù)流程圖寫框架

一個功能一個功能實現(xiàn)

3.流程圖

4.代碼實現(xiàn)

4.1頭文件

#ifndef __MYHEAD_H__
#define __MYHEAD_H__
 
#include <head.h>
#define N 512
//聊天操作用的結(jié)構(gòu)體
typedef struct _MSG{
    char ch;//用來'l'聊天,'q'退出,'登錄d'
    char name[128];//存名字
    char text[N];//存聊天內(nèi)容
}msg_t;
//用來保存每個用戶信息的結(jié)構(gòu)體
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);
#endif

4.2函數(shù)

#include "myhead.h"
 
//創(chuàng)建一個單鏈表頭
int create_head(jilu_t **head)
{   
    if(head==NULL){
        printf("傳送錯誤,請檢查\n");
        return -1;
    }
 
    (*head)=(jilu_t *)malloc(sizeof(jilu_t));
    (*head)->next=NULL;
 
    return 0;
 
}
 
//記錄登錄的用戶的信息
int input_addr(jilu_t *head,msg_t msg,int sockfd,struct sockaddr_in clientaddr,socklen_t clientaddr_len)
{
    if(head==NULL){
        printf("傳送錯誤,請檢查\n");
        return -1;
    }
 
    //將這個用戶登錄的信息發(fā)送給所有人
    snprintf(msg.text,sizeof(msg.text),"[%s]%s",msg.name,"登錄了");
    //這個用來記錄頭的地址
    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("將用戶登錄信息發(fā)給所有人失敗");
        }
    }
    //創(chuàng)建一個新的節(jié)點,并且把新的用戶信息放入新得單列表
    jilu_t *temp=NULL;
    create_head(&temp);
    temp->addr=clientaddr;
 
    //用頭插法將用戶信息插入鏈表
    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("傳送錯誤,請檢查\n");
        return -1;
    }
 
    //將接受到的消息發(fā)給除了自己以外的所有人
    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("將聊天內(nèi)容發(fā)給所有人失敗");
            }
        }
    }
 
    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("傳送錯誤,請檢查\n");
        return -1;
    }
 
    snprintf(msg.text,sizeof(msg.text),"%s%s",msg.name,"退出登錄");
 
    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("將這個退出的信息告訴所有人失敗");
            }
        }
    }
 
   
    return 0;
}

4.3服務(wù)器

#include "myhead.h"
 
int main(int argc, char const *argv[])
{
    int sockfd=0;
    pid_t pid=0;
    msg_t msg;//用來進(jìn)行各種操作
    msg_t faso;//用來發(fā)系統(tǒng)消息
 
    if((sockfd=socket(AF_INET,SOCK_DGRAM,0))==-1){
        ERRLOG("創(chuàng)建服務(wù)器套接字失敗");
    }
 
    //將網(wǎng)絡(luò)信息結(jié)構(gòu)體放入服務(wù)器中
    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);
 
    //將套接字與網(wǎng)絡(luò)信息結(jié)構(gòu)體綁定
    if(bind(sockfd,(struct sockaddr*)&serveraddr,serveraddr_len)==-1){
        ERRLOG("將套接字與網(wǎng)絡(luò)信息結(jié)構(gòu)體綁定失敗");
    }
 
    //創(chuàng)建一個新的網(wǎng)絡(luò)信息結(jié)構(gòu)體來存客戶端的信息
    struct sockaddr_in clientaddr;
    clientaddr.sin_family=AF_INET;
    socklen_t clientaddr_len=sizeof(clientaddr);
    
    //創(chuàng)建進(jìn)程
    pid=fork();
    if(pid==-1){
        ERRLOG("服務(wù)器創(chuàng)建進(jìn)程失敗");
    }else if(pid==0){
        //創(chuàng)建一個單列表保存網(wǎng)絡(luò)信息結(jié)構(gòu)體
        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("接受客戶端傳來的信息失敗");
            }          
             switch(msg.ch){
                case 'd'://登錄信息
                    input_addr(head,msg,sockfd,clientaddr,clientaddr_len);
                    //head->next=NULL; //這個用來測試用的                  
                    break;
                case 'l'://聊天信息
                    wx_addr(head,msg,sockfd,clientaddr,clientaddr_len);
                    break;
                case 'q'://退出信息
                    tuichu_addr(head,msg,sockfd,clientaddr,clientaddr_len);
                    break;
            }
        }
    }else{
        while(1){
            //發(fā)系統(tǒng)消息
            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","系統(tǒng)消息");
 
            if(sendto(sockfd,&faso,sizeof(faso),0,(struct sockaddr*)&serveraddr,serveraddr_len)==-1){
                ERRLOG("發(fā)送系統(tǒng)消息失敗");
            }
        }
    }
    return 0;
}

4.4客戶端

#include "myhead.h"
 
 
int main(int argc, char const *argv[])
{
 
    //判斷輸入的對不對
    if(argc!=3){
        printf("輸入格式錯誤,./a.out ip port\n");
        exit(EXIT_SUCCESS);
    }
 
    int sockfd=0;
    pid_t pid=0;
    msg_t msg;//創(chuàng)建發(fā)送用戶的信息
    
 
    if((sockfd=socket(AF_INET,SOCK_DGRAM,0))==-1){
        ERRLOG("創(chuàng)建客戶端套接字失敗");
    }
 
    //將客戶端網(wǎng)絡(luò)信息結(jié)構(gòu)體進(jìn)行綁定
    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);
 
    //輸入用戶的姓名進(jìn)行登錄操作
    msg.ch='d';
    printf("請輸入你用來登錄的姓名");
    fgets(msg.name,sizeof(msg.name),stdin);
    msg.name[strlen(msg.name)-1]='\0';
 
    //給服務(wù)器發(fā)送用戶已經(jīng)登錄上的操作
    if(sendto(sockfd,&msg,sizeof(msg),0,(struct sockaddr*)&clientaddr,clientaddr_len)==-1){
        ERRLOG("客戶端給服務(wù)器發(fā)送的登錄信息失敗");
    }
    
    //創(chuàng)建進(jìn)程,子進(jìn)程用來接受,父進(jìn)程用來發(fā)送
    pid=fork();
    if(pid==-1){
        ERRLOG("客戶端創(chuàng)建進(jìn)程失敗");
    }else if(pid==0){
        //用來接受服務(wù)器發(fā)來的消息
        while(1){
            memset(&msg,0,sizeof(msg));
            if(recvfrom(sockfd,&msg,sizeof(msg),0,NULL,NULL)==-1){
                ERRLOG("接受服務(wù)器發(fā)來的信息錯誤");
            }
 
            printf("[%s]>>(%s)\n",msg.name,msg.text);
        }
    }else{
        //寫入要判聊天的內(nèi)容
        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';
            }
            
            //將寫好的內(nèi)容發(fā)送給服務(wù)器
            if(sendto(sockfd,&msg,sizeof(msg),0,(struct sockaddr*)&clientaddr,clientaddr_len)==-1){
                ERRLOG("將聊天內(nèi)容發(fā)送給服務(wù)器失敗");
            }
 
            //當(dāng)識別到停止的時候,關(guān)閉進(jìn)程
            if(strncmp("quit",msg.text,5)==0){
                kill(pid,SIGKILL);
                close(sockfd);
                exit(EXIT_SUCCESS);
            }
        }
    }   
 
    return 0;
}

到此這篇關(guān)于C語言利用UDP實現(xiàn)群聊聊天室的示例代碼的文章就介紹到這了,更多相關(guān)C語言 UDP聊天室內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C語言繪制簡單時鐘小程序

    C語言繪制簡單時鐘小程序

    這篇文章主要為大家詳細(xì)介紹了C語言繪制簡單時鐘小程序,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-06-06
  • C++ OpenCV繪制幾何圖形

    C++ OpenCV繪制幾何圖形

    這篇文章主要為大家詳細(xì)介紹了C++ OpenCV繪制幾何圖形,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-10-10
  • C語言實現(xiàn)萬年歷小程序

    C語言實現(xiàn)萬年歷小程序

    這篇文章主要為大家詳細(xì)介紹了C語言實現(xiàn)萬年歷小程序,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-10-10
  • C++中4種類型轉(zhuǎn)換的方法分享

    C++中4種類型轉(zhuǎn)換的方法分享

    這篇文章主要為大家詳細(xì)介紹了C++中4種類型轉(zhuǎn)換的方法,文中的示例代碼講解詳細(xì),對我們學(xué)習(xí)C++有一定的幫助,感興趣的可以了解一下
    2023-04-04
  • vscode配置gitbash終端的方法步驟

    vscode配置gitbash終端的方法步驟

    本文主要介紹了vscode配置gitbash終端的方法步驟,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-06-06
  • C語言實現(xiàn)最簡單的剪刀石頭布小游戲示例

    C語言實現(xiàn)最簡單的剪刀石頭布小游戲示例

    這篇文章主要介紹了C語言實現(xiàn)最簡單的剪刀石頭布小游戲,涉及C語言數(shù)組、隨機數(shù)與數(shù)值運算等相關(guān)操作技巧,需要的朋友可以參考下
    2017-09-09
  • C語言實現(xiàn)放煙花的程序

    C語言實現(xiàn)放煙花的程序

    這篇文章主要為大家詳細(xì)介紹了C語言實現(xiàn)放煙花的程序,有音樂播放,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-02-02
  • C++ Boost Container庫示例詳細(xì)講解

    C++ Boost Container庫示例詳細(xì)講解

    Boost是為C++語言標(biāo)準(zhǔn)庫提供擴展的一些C++程序庫的總稱。Boost庫是一個可移植、提供源代碼的C++庫,作為標(biāo)準(zhǔn)庫的后備,是C++標(biāo)準(zhǔn)化進(jìn)程的開發(fā)引擎之一,是為C++語言標(biāo)準(zhǔn)庫提供擴展的一些C++程序庫的總稱
    2022-11-11
  • C++實現(xiàn)單例模式日志輸出詳解

    C++實現(xiàn)單例模式日志輸出詳解

    這篇文章主要為大家詳細(xì)介紹了C++中單例模式的相關(guān)知識,并給出單例模式日志實現(xiàn),文中的示例代碼講解詳細(xì),感興趣的小伙伴可以了解一下
    2023-04-04
  • C語言實現(xiàn)查詢自動售貨機中的商品價格【實例分享】

    C語言實現(xiàn)查詢自動售貨機中的商品價格【實例分享】

    本文主要介紹了C語言實現(xiàn)查詢自動售貨機中的商品價格的相關(guān)資料。具有很好的參考價值。下面跟著小編一起來看下吧
    2017-04-04

最新評論

明星| 苍山县| 来宾市| 盱眙县| 雷波县| 河源市| 马龙县| 石阡县| 奎屯市| 恭城| 秦皇岛市| 咸宁市| 双城市| 四会市| 伊通| 汉中市| 淮阳县| 林甸县| 博湖县| 张家港市| 辽宁省| 海门市| 中山市| 洪江市| 宜宾市| 白银市| 白水县| 丰镇市| 五常市| 岱山县| 高碑店市| 壶关县| 西盟| 淳安县| 同仁县| 环江| 清水县| 石台县| 龙胜| 莲花县| 深水埗区|