linux中socket的基本用法——UDP篇

先记录下关于UDP的基础知识点

UDP的基础知识点
包括的头文件和常用的函数
#include <sys/types.h>          
#include <sys/socket.h>

1.socket函数原型
    int socket(int domain, int type, int protocol);    
功能:
    创建一个socket
参数说明:
    参数1:设置网络通信的域 这里的AF_INET 表示IPV4的网络类型;使用AF_INET6的网络类型
    参数2:socket的数据类型 这里的SOCK_DGRAM表示UDP类型;使用SOCK_STREAM表示TCP类型
    参数3:协议类型 一般置为0
例子:
    int sockfd = socket(AF_INET,SOCK_DGRAM,0);
    
2.sendto函数原型
    ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
              const struct sockaddr *dest_addr, socklen_t addrlen);
功能:
    sendto发送指令给指定的服务器
参数说明:
    参数1:监听端口的套接字文件描述符 通过socket返回
    参数2:发送缓冲区
    参数3:缓冲区的大小
    参数4:一般置为0
    参数5:sockaddr结构体地址 这个结构体包含 IP地址 端口号 网络通信域
    参数6:参数5的长度 可以用sizeof(sockaddr_in)获取
例子:
    int sendlength = sendto(sockfd,buffer,strlen(buffer),0, (struct sockaddr*)addr, len);

3.recvfrom函数原型
    ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,
                struct sockaddr *src_addr, socklen_t *addrlen);
功能:
    接收服务端返回的信息
参数说明:
    第一个参数sockfd:正在监听端口的套接口文件描述符,通过socket获得
    第二个参数buf:接收缓冲区,往往是使用者定义的数组,该数组装有接收到的数据
    第三个参数len:接收缓冲区的大小,单位是字节
    第四个参数flags:填0即可
    第五个参数src_addr:指向发送数据的主机地址信息的结构体,也就是我们可以从该参数获取到数据是谁发出的
    第六个参数addrlen:表示第五个参数所指向内容的长度
    返回值:成功:返回接收成功的数据长度 失败 返回-1
     

进行UDP通信的时候 端口是一定要一致的 否则无法收到消息

//Step2 给sockaddr_in结构体赋值(IP地址 端口号 网络通信域)
    bzero(&addr,sizeof(struct sockaddr_in)); 
    addr.sin_family=AF_INET; 
    addr.sin_port=htons(SERVER_PORT);
    //addr.sin_addr.s_addr = htonl("139.224.117.109");
    //inet_aton("139.224.117.109", &addr.sin_addr);
    if(inet_aton("127.0.0.1",&addr.sin_addr)<0)

例子:
        struct sockaddr_in addr; 
    bzero(&addr,sizeof(struct sockaddr_in));
    addr.sin_family = AF_INET; 
    addr.sin_port = htons(SERVER_PORT);
    addr.sin_addr.s_addr = inet_addr("127.0.0.1");

UDP的server例子:

/*
2019-11-30 11:24:14
一个简单的UDP server的实现
*/

#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <netdb.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <arpa/inet.h>

#define SERVER_PORT 9989 
#define MAX_MSG_SIZE 1024 

int main() 
{ 
    int sockfd;
    int addrlen,n;
    char msg[MAX_MSG_SIZE];
    struct sockaddr_in addr;
    
    //Step1 创建socket
    sockfd=socket(AF_INET,SOCK_DGRAM,0); 

    if(sockfd<0)
    {
        fprintf(stderr,"Socket Error:%s\n",strerror(errno)); 
        exit(1); 
    }

    //Step2 给sockaddr_in结构体赋值
    bzero(&addr,sizeof(struct sockaddr_in)); 
    addr.sin_family=AF_INET; 
    addr.sin_addr.s_addr=htonl(INADDR_ANY); 
    addr.sin_port=htons(SERVER_PORT); 
    
    //Step3 绑定sock
    if(bind(sockfd,(struct sockaddr *)&addr,sizeof(struct sockaddr_in))<0)
    { 
        fprintf(stderr,"Bind Error:%s\n",strerror(errno)); 
        exit(1); 
    }

    while(1) 
    {
        bzero(msg,sizeof(msg));
        //Step4 开始接收消息(来自客户端的消息)
        n=recvfrom(sockfd,msg,MAX_MSG_SIZE,0,(struct sockaddr*)&addr,&sizeof(struct sockaddr_in));
        if (n <= 0)
            break;
        fprintf(stdout,"Server have received: %s\n",msg);
        //这里做一个正常退出的条件
        if (strcmp(msg,"exit\n") == 0)
        {
            printf("Exit server\n");
            break;
        }
    } 

    //Step5 当接收到的值异常的时候 结束这个流程 释放socket
    close(sockfd); 
} 

UDP client的例子

/*
2019-11-30 11:32:19
一个简单的UDP的client
*/

#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <netdb.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <arpa/inet.h>

#define SERVER_PORT 9999 
#define MAX_BUF_SIZE 1024

int main() 
{
    char buffer[MAX_BUF_SIZE]; 
    int sockfd,n; 
    struct sockaddr_in addr;

    //Step1 创建socket
    sockfd=socket(AF_INET,SOCK_DGRAM,0); 
    if(sockfd<0) 
    { 
        fprintf(stderr,"Socket Error:%s\n",strerror(errno)); 
        exit(1); 
    } 

    //Step2 对sockaddr_in进行赋值
    bzero(&addr,sizeof(struct sockaddr_in)); 
    addr.sin_family=AF_INET; 
    addr.sin_port=htons(SERVER_PORT);
    addr.sin_addr.s_addr = inet_addr("127.0.0.1");

    while(1) 
    { 
        bzero(buffer,MAX_BUF_SIZE); 
        printf("Please input char:\n");
        fgets(buffer,MAX_BUF_SIZE,stdin);
        //Step3 发送消息到服务端
        sendto(sockfd,buffer,strlen(buffer),0, (struct sockaddr *)&addr, sizeof(struct sockaddr_in));
         //这里做一个退出的条件 输入exit的时候退出
        if (strcmp(buffer,"exit\n") == 0)
            break;
    }

    //Step4 结束消息
    close(sockfd); 

} 

编译就使用gcc来进行编译就好了

gcc -o client client.c

gcc -o server server.c

 

运行结果:

 

这里记录一个问题(一个警告)

example_tcp_client.c:53:5: warning: implicit declaration of function ‘write’ [-Wimplicit-function-declaration]
     write(sockfd,buffer,strlen(buffer)); 
     ^
example_tcp_client.c:56:5: warning: implicit declaration of function ‘close’ [-Wimplicit-function-declaration]
     close(sockfd); 

这个严格上说不算错误 只是警告,这里加上头文件 #include <unistd.h> 即可解决此问题

 

 

Guess you like

Origin blog.csdn.net/Wuzm_/article/details/103322336