UDP----socket通信

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了UDP----socket通信相关的知识,希望对你有一定的参考价值。

基于UDP(不是面向连接)的socket编程,分为客户端和服务器端。

客户端的流程如下:

(1)创建套接字(socket)

(2)和服务器端进行通信(sendto)

(3)关闭套接字

sendto函数:指向一指定目的地发送数据,sendto()适用于发送未建立连接的UDP数据包 

ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,

                      const struct sockaddr *dest_addr, socklen_t addrlen);


返回值为整型,如果成功,则返回发送的字节数,失败则返回SOCKET_ERROR。

sockfd: 套接字

buf: 待发送数据的缓冲区

len: 缓冲区长度

flags:调用方式标志位, 一般为0, 改变Flags,将会改变Sendto发送的形式:阻塞

addr:(可选)指针,指向目的套接字的地址

addr:lenaddr所指地址的长度

服务器端的流程如下:

(1)创建套接字(socket)

(2)将套接字绑定到一个本地地址和端口上(bind)

(3)用返回的套接字和客户端进行通信(recvfrom)

(4)返回,等待另一个客户请求。

(5)关闭套接字。

recvfrom函数:本函数用于从(已连接)套接口上接收数据,并捕获数据发送源的地址。

#include <sys/types.h>

#include <sys/socket.h>

ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,

                        struct sockaddr *src_addr, socklen_t *addrlen);

sockfd:标识一个已连接套接口的描述字。

buf:接收数据缓冲区

len:缓冲区长度。

flags:调用操作方式。

src_addr:(可选)指针,指向装有源地址的缓冲区。——输出型参数

addrlen:(可选)指针,指向from缓冲区长度值。——输入输出型参数。

返回值为整型,如果成功,则返回接收到的字节数,失败则返回SOCKET_ERROR。

//server端
#include<stdio.h>                                                                      
#include<stdlib.h>
#include<errno.h>
#include<string.h>
#include<sys/socket.h>
#include<sys/types.h>
#include<netinet/in.h>
#include<arpa/inet.h>
void Usage(const char* proc)
{
    printf("%s [ip][port]\n");
}
int main(int argc,char* argv[])
{
    if(argc!=3){
        Usage(argv[0]);
        return 1;
    }
    int sock=socket(AF_INET,SOCK_DGRAM,0);
    if(sock<0){
        perror("socket");
        return 2;
    }
    int _port=atoi(argv[2]);
    char* _ip=argv[1];
    struct sockaddr_in local;
    local.sin_family=AF_INET;
    local.sin_port=htons(_port);
    local.sin_addr.s_addr=inet_addr(_ip);
    if(bind(sock,(struct sockaddr*)&local,sizeof(local))<0){
        perror("bind");
        exit(1);
    }
    char buf[1024];
    struct sockaddr_in remote;
    socklen_t len=sizeof(remote);
    while(1)
    {
        ssize_t _s=recvfrom(sock,buf,sizeof(buf)-1,0,(struct sockaddr*)&remote,&len);
        if(_s>0)
        {
            buf[_s]=‘\0‘;
            printf("client:[ip:%s][port:%d]  %s",inet_ntoa(remote.sin_addr),ntohs(remote.sin_port),buf);
         }
         else if(_s==0){
            printf("client close");
            break;
        }
        else
        {
            break;
        }

    }
    close(sock);
    return 0;
}
//client端
#include<stdio.h>                                                                      
#include<stdlib.h>
#include<errno.h>
#include<sys/socket.h>
#include<sys/types.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<string.h>
void Usage(const char* proc)
{
    printf("%s[ip][port]",proc);
}
int main(int argc,char* argv[])
{
    if(argc!=3){
        Usage(argv[0]);
        return 1;
    }
    int sock=socket(AF_INET,SOCK_DGRAM,0);
    if(sock<0){
        perror("socket");
        return 2;
    }
    int _port=atoi(argv[2]);
    char* _ip=argv[1];
    struct sockaddr_in client;
    client.sin_family=AF_INET;
    client.sin_port=htons(_port);
    client.sin_addr.s_addr=inet_addr(_ip);
    char buf[1024];
    while(1)
    {
        ssize_t _s=read(0,buf,sizeof(buf)-1);
        if(_s>0){
            buf[_s]=‘\0‘;
        }
        _s=sendto(sock,buf,sizeof(buf)-1,0,(struct sockaddr*)&client,sizeof(client));
    }
    return 0;
}

运行截图:

技术分享

本文出自 “小止” 博客,请务必保留此出处http://10541556.blog.51cto.com/10531556/1775684

以上是关于UDP----socket通信的主要内容,如果未能解决你的问题,请参考以下文章

Linux客户端和Window服务器端udp socket通信不能成功

深入浅出讲解:php的socket通信

UDP Socket 接收垃圾值

网络通信协议下的 TCP(三次握手,四次挥手) 和 UDP socket 套接字

[转]Socket通信原理

Socket通信原理