网络编程的学习之udp

Udp编程过程

Sento不会阻塞

实现聊天室效果

上线

聊天

下线

服务端需要一个地址,去保留名字和ip地址

交互的时候发结构体

下面这个宏只能在c语言里使用

ser.sin_port = htons(50000);

上面是端口号50000以上,两边要一样

这里是不要让udp发的太快,发个东西过去

收和发的时候次数要一致

无状态的

为什么右边写在里面比较结束标志

验证了udp发送接收的数据是有边界

Netstat可以查看网络状态

服务器端

cs 复制代码
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
#include <time.h>
typedef struct sockaddr * (SA);
typedef enum {CMD_LOGIN,CMD_CHAT,CMD_LOGOUT}TYPE;
typedef struct 
{
    TYPE type;
    char name[50];
    char context[128];

}MSG;
typedef struct 
{
    struct sockaddr_in cli;
    int flag; // 0  free 1 occu
}LIST;
#define MAX 10
LIST list[MAX]={0};
int do_login(int sockfd,MSG* msg,struct sockaddr_in* cli)
{
    int i = 0 ;
    for(i=0;i<MAX;i++)
    {
        if(1 == list[i].flag )
        {
            sendto(sockfd,msg,sizeof(MSG),0,(SA)&list[i].cli,sizeof(list[i].cli));
        }
    }
    for(i=0;i<MAX;i++)
    {
        if(0 == list[i].flag )
        {
            list[i].flag =1;
            //list[i].cli = *cli;
            memcpy(&list[i].cli,cli,sizeof(*cli));
            break;
        }
    }
    return 0;
}

int do_chat(int sockfd, MSG* msg,struct sockaddr_in*cli)
{
     int i = 0 ;
    for(i=0;i<MAX;i++)
    {
        if(1 == list[i].flag && 0!=memcmp(&list[i].cli,cli,sizeof(*cli)) )
        {
            sendto(sockfd,msg,sizeof(MSG),0,(SA)&list[i].cli,sizeof(list[i].cli));
        }
    }
}
int do_logout(int sockfd, MSG* msg,struct sockaddr_in*cli)
{
    return 0;
}
int main(int argc, char *argv[])
{
    int sockfd = socket(AF_INET,SOCK_DGRAM,0);
    if(-1 == sockfd)
    {
        perror("socket");
        exit(1);
    }

    // man 7 ip 
    struct sockaddr_in ser,cli;
    bzero(&ser,sizeof(ser));
    bzero(&cli,sizeof(cli));
    ser.sin_family = AF_INET;
    // 大小端转化 host to net short 
    ser.sin_port = htons(50000);
    ser.sin_addr.s_addr = inet_addr("127.0.0.1");
    int ret = bind(sockfd,(SA)&ser,sizeof(ser));
    if(-1 == ret)
    {
        perror("bind");
        exit(1);
    }
    socklen_t len = sizeof(cli);
    MSG msg;
    while(1)
    {
        bzero(&msg,sizeof(msg));
        recvfrom(sockfd,&msg,sizeof(msg),0,(SA)&cli,&len);
        switch(msg.type)
        {
            case CMD_LOGIN:
                do_login(sockfd,&msg,&cli);
                break;
            case CMD_LOGOUT:
                do_logout(sockfd,&msg,&cli);
                break;
            case CMD_CHAT:
                do_chat(sockfd,&msg,&cli);
                break;
        
        }
    }
    close(sockfd);
    return 0;
}

用户端

cs 复制代码
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
#include <time.h>
typedef struct sockaddr * (SA);
typedef enum {CMD_LOGIN,CMD_CHAT,CMD_LOGOUT}TYPE;
typedef struct 
{
    TYPE type;
    char name[50];
    char context[128];

}MSG;
int main(int argc, char *argv[])
{
    int sockfd = socket(AF_INET,SOCK_DGRAM,0);
    if(-1 == sockfd)
    {
        perror("socket");
        exit(1);
    }

    // man 7 ip 
    struct sockaddr_in ser,cli;
    bzero(&ser,sizeof(ser));
    ser.sin_family = AF_INET;
    // 大小端转化 host to net short 
    ser.sin_port = htons(50000);
    ser.sin_addr.s_addr = inet_addr("127.0.0.1");
    socklen_t len = sizeof(cli);
    MSG msg;
    char name[50]={0};
    printf("input name:");
    fgets(name,sizeof(name),stdin);
    name[strlen(name)-1]='\0';

    msg.type = CMD_LOGIN;
    strcpy(msg.name ,name);
    strcpy(msg.context,"login");

    sendto(sockfd,&msg,sizeof(msg),0,(SA)&ser,sizeof(ser));

    pid_t pid = fork();
    if(pid>0)
    {
        while(1)
        {
            bzero(&msg,sizeof(msg));
            recvfrom(sockfd,&msg,sizeof(msg),0,NULL,NULL);    
            printf("%s:%s\n",msg.name,msg.context);
        }
    }
    else if(0==pid)
    {
        while(1)
        {
            printf("to all");    
            char buf[128]={0};
            strcpy(msg.name,name);
            msg.type = CMD_CHAT;
            fgets(msg.context,sizeof(msg.context),stdin);//#quit
            msg.context[strlen(msg.context)-1]='\0';
            if(0==strcmp(msg.context,"#quit"))
            {
                msg.type = CMD_LOGOUT;
                strcpy(msg.context,"CMD_LOGOUT");
            }
            sendto(sockfd,&msg,sizeof(msg),0,(SA)&ser,sizeof(ser));
        }
    }
    else 
    {
        perror("fork");
        exit(1);
    }
    close(sockfd);
    return 0;
}
相关推荐
Re.不晚几秒前
Java入门15——抽象类
java·开发语言·学习·算法·intellij-idea
vip45114 分钟前
Linux 经典面试八股文
linux
大霞上仙16 分钟前
Ubuntu系统电脑没有WiFi适配器
linux·运维·电脑
weixin_4426434234 分钟前
推荐FileLink数据跨网摆渡系统 — 安全、高效的数据传输解决方案
服务器·网络·安全·filelink数据摆渡系统
阑梦清川1 小时前
JavaEE初阶---网络原理(五)---HTTP协议
网络·http·java-ee
幼儿园老大*1 小时前
走进 Go 语言基础语法
开发语言·后端·学习·golang·go
1 小时前
开源竞争-数据驱动成长-11/05-大专生的思考
人工智能·笔记·学习·算法·机器学习
ctrey_1 小时前
2024-11-4 学习人工智能的Day21 openCV(3)
人工智能·opencv·学习
~yY…s<#>1 小时前
【刷题17】最小栈、栈的压入弹出、逆波兰表达式
c语言·数据结构·c++·算法·leetcode
啦啦右一1 小时前
前端 | MYTED单篇TED词汇学习功能优化
前端·学习