网络编程3 - UDP套接口编程

网络编程3 - UDP套接口编程

UDP程序同样分为服务端server_udp.c和客户端client_udp.c两部分。
两部分的基本步骤如下:
服务端:socket -> bind -> recvfrom -> sendto -> close
客户端:socket -> sendto -> recvfrm -> close

可以看到,UDP编程中没有了TCP编程中的connect(), listen(), accept()。主要通过recvfrom()和sendto()来完成信息的收发。

1.数据发送函数
#include <sys/socket.h>
ssize_t sendto (int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *toaddr, socklen_t addrlen);
返回:成功则返回实际发送的字节数,出错返回-1。
参数:sockfd为套接口描述符,buf指向数据发送缓冲区,len为发送数据的长度,flags一般为0,toaddr指向目标套接口,addrlen为套接口数据的长度。


2.数据接收函数
ssize_t recvfrom (int sockfd, void *buf, size_t len, int flags, struct sockaddr *fromaddr, socklen_t *addrlen);
返回:成功则返回实际接收的字节数,出错返回-1。
参数:sockfd为套接口描述符,buf指向数据发送缓冲区,len为发送数据的长度,flags一般为0,fromaddr指向源套接口,addrlen为套接口数据的长度。

备注:sockfd应该是socket file describer的意思,也就是说socket的描述符类似于一个文件描述符,一个socket对应一个文件。socket的创建过程主要是声明协议,网络类型,也就是相当于文件类型。而真正的套接口数据结构sockadddr则包含了套接口的数据源,类似于文件的数据来源——屏幕或键盘等可以传递信息的节点。设定好文件类型和文件的数据来源后,就可以使用write,read,sendto,recvfrom等函数读写文件了。


3.服务端程序
server_udp.c代码如下:

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <memory.h>

#define MAX_SIZE 1024

int main(int argc, char *argv[])
{
    int PORT;
    if( argc!=2 || (argc==2 && (PORT=atoi(argv[1]))<0) )
    {
        printf("please input the port like 8888");
        exit(1);
    }

    int sockfd = socket(AF_INET,SOCK_DGRAM,0);
    if(sockfd<0)
    {
        perror("socket create error\n");
        exit(1);
    }
    struct sockaddr_in addr;
    int addrlen = sizeof(struct sockaddr_in);
    bzero(&addr,addrlen);
    addr.sin_family=AF_INET;
    addr.sin_addr.s_addr=htonl(INADDR_ANY);
    addr.sin_port=htons(PORT);
    if( bind(sockfd,(struct sockaddr*)(&addr),addrlen)<0 )
    {
        perror("bind error\n");
        exit(1);
    }
    char msg[MAX_SIZE];
    int n;
    while(1)
    {
        bzero(msg,MAX_SIZE);
        n=recvfrom(sockfd,msg,sizeof(msg),0,(struct sockaddr*)(&addr),&addrlen);
        printf("Receive messgae from client:%s",msg);
        printf("please input message from server endpoint\n");
        fgets(msg,MAX_SIZE,stdin);
        printf("Server endpoint input message:%s",msg);
        sendto(sockfd,msg,n,0,(struct sockaddr*)(&addr),addrlen);
    }
    close(sockfd);
    return 0;
}

4.客户端程序
client_udp代码如下:

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <memory.h>
#define MAX_SIZE 1024

int main(int argc, char *argv[])
{
    if(3!=argc)
    {
        printf("please input two parameter: IP and port\n");
        exit(1);
    }
    uint16_t port;
    if( (port=atoi(argv[2]))<0 )
    {
        printf("ensure port > 0\n");
        exit(1);
    }
    int sockfd = socket(AF_INET,SOCK_DGRAM,0);
    if(sockfd<0)
    {
        printf("socket create error\n");
        exit(1);
    }
    int addrlen=sizeof(struct sockaddr_in);
    struct sockaddr_in addr;
    bzero(&addr,addrlen);
    addr.sin_family=AF_INET;
    addr.sin_port=htons(port);
    if(inet_aton(argv[1],&addr.sin_addr)<0) //IP字符串转换为sin_addr地址
    {
        printf("IP error\n");
        exit(1);
    }
    char buffer[MAX_SIZE];
    int n;
    while(1)
    {
        bzero(buffer,MAX_SIZE);
        printf("please input message from client endpoint\n");
        fgets(buffer,MAX_SIZE,stdin);
        sendto(sockfd,buffer,strlen(buffer),0,(struct sockaddr*)(&addr),addrlen);
        printf("client endpoint input message:%s\n",buffer);
        n=recvfrom(sockfd,buffer,MAX_SIZE,0,(struct sockaddr*)(&addr),&addrlen);
        printf("receive message from server:%s\n",buffer);
    }
    close(sockfd);
    return 0;
}


运行过程:
生成server_udp,client_udp两个可执行程序,分别在两个终端中运行。

服务端输入:./server_udp 3456

客户端
输入:./client_dup localhost 3456
输出:please input message from client endpoint
输入:hello. this is msg from client!
输出:client endpoint input message:hello. this is msg from client!

同时,服务端输出:Receive messgae from client:hello. this is msg from client!
please input message from server endpoint
输入:Hi. This is msg from server!!
输出:Server endpoint input message:Hi. This is msg from server!!
...

可以看到,客户端和服务端能够相互发送消息。但是,以客户端为例,不能一边等待消息,一边发送消息。这种行为可能要求用到多线程处理,后面再完善。


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值