udp program

UDP program

UDP常用函数:recvfrom和sendto

  • recvfrom

ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr * from, socklen_t *addrlen);

  • sendto

ssize_t sendto(int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *to, socklen_t addrlen);

sockfd, buf,len和read,write一样。

recvfrom负责从sockfd接收数据,如果from不是NULL,那么在from里面存储了信息来源的情况,如果对信息来源不感兴趣,可以将from和addrlen设置为NULL。

sendto负责向to发送信息,此时在to里面存储了收信息方的详细资料。

flags一般设置为0即可。

返回值:成功返回发送或接收的字节数,失败返回-1,并且设置errno。

注:recvfrom中addrlen一定要正确初始化,否则引起错误。

The argument addrlen is a value-result argument, which the caller should initialize before the call to the size of the buffer associated with from, and modified on return to indicate the actual size of the source address. The returned address is truncated if the buffer provided is too small; in this case, addrlen will return a value greater than was supplied to the call.

注:sendto对方主机崩溃或主程序关闭,也可成功返回发送字节数。(UDP直接把数据发送给IP层就算成功了。)

 

服务器端:socket -> bind -> recvfrom -> sendto -> close

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

char rbuf[50];
 
int main()
{
    int sockfd;
    int size;
    int ret;
    int on =1;
    struct sockaddr_in saddr;
    struct sockaddr_in raddr;
 
    //设置地址信息,ip信息
    size = sizeof(struct sockaddr_in);
    bzero(&saddr,size);
    saddr.sin_family = AF_INET;
    saddr.sin_port = htons(10001);
    saddr.sin_addr.s_addr = htonl(INADDR_ANY);
 
    //创建udp 的套接字
    sockfd = socket(AF_INET,SOCK_DGRAM,0);
    if(sockfd<0)
    {
        perror("socket failed");
        return -1;
    }
 
    //设置端口复用
    setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(on)); 
 
    //绑定地址信息,ip信息
    ret = bind(sockfd,(struct sockaddr*)&saddr,sizeof(struct sockaddr));
    if(ret<0)
    {
        perror("sbind failed");
        return -1;
    }
 
    int val = sizeof(struct sockaddr);
    //循环接收客户端发来的消息
    while(1)
    {
        puts("waiting data");
        ret=recvfrom(sockfd,rbuf,50,0,(struct sockaddr*)&raddr,&val);
        if(ret <0)
        {
            perror("recvfrom failed");
        }
 
        printf("the data :%s\n",rbuf);
        bzero(rbuf,50);
    }
    //关闭udp套接字,这里不可达的。
    close(sockfd);
    return 0;
}

客户端: socket -> sendto -> recvfrom -> close

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <unistd.h>
#include <signal.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netinet/in.h>

char wbuf[50];
 
int main()
{
    int sockfd;
    int size,on = 1;
    struct sockaddr_in saddr;
    int ret;
 
    size = sizeof(struct sockaddr_in);
    bzero(&saddr,size);
 
    //设置地址信息,ip信息
    saddr.sin_family = AF_INET;
    saddr.sin_port = htons(10001);
    saddr.sin_addr.s_addr = inet_addr("127.0.0.1");//192.168.152.128为服务端所在的ip,由于本代码是本机测试,所以写的是自己的ip
 
    //创建udp 的套接字
    sockfd= socket(AF_INET,SOCK_DGRAM,0);
    if(sockfd<0)
    {
        perror("failed socket");
        return -1;
    }
    //设置端口复用
    setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(on));
 
    //循环发送信息给服务端
    while(1)
    {
        puts("please enter data:");
        scanf("%s",wbuf);
        ret=sendto(sockfd,wbuf,50,0,(struct sockaddr*)&saddr,
            sizeof(struct sockaddr));
        if(ret<0)
        {
            perror("sendto failed");
        }
 
        bzero(wbuf,50);
    }
    close(sockfd);
    return 0;
}

 

posted @ 2015-11-29 12:52  yuxi_o  阅读(270)  评论(0编辑  收藏  举报