实现简单UDP服务器客户端模型

来源:互联网 发布:皮影客电脑软件下载 编辑:程序博客网 时间:2024/05/31 05:27
UDP是无连接的,在数据的发送之前不需要连接,只需要知道要发数据给谁,然后将数据发出即可,可以直接接收到其他人发来的数据,不必调用listen()和accept()函数。所以UDP中建立好套接字后,就可以直接进行数据的传输。

基于UDP的接收和发送函数:
#include <sys/types.h>
#include <sys/socket.h>
ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,  const struct sockaddr *dest_addr, socklen_t addrlen);
函数说明:
     sendto() 用来将数据由指定的socket 传给对方主机.
参数描述:
     sockfd: 为已建好连线的socket, 如果利用UDP协议则不需经过连线操作
     buf: 缓冲区
     len:buf的大小
     flags: 一般设0
     dest_addr: 用来指定欲传送的网络地址, 结构sockaddr 请参考bind()
     addrlen: 为sockaddr 的结构长度.

返回值:
     成功则返回实际传送出去的字符数, 失败返回-1, 错误原因存于errno 中.

ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,  struct sockaddr *src_addr, socklen_t *addrlen);
函数说明:
     用来接收远程主机经指定的socket 传来的数据, 并把数据存到由参数buf 指向的内存空间
参数描述:
     sockfd:为已建好连线的socket
     buf:缓冲区
     len:buf大小
     flags:收取收取数据的方式
     src_addr: 用来指定欲传送的网络地址, 结构sockaddr 请参考bind()
     addrlen:为sockaddr 的结构长度
返回值:
     成功则返回接收到的字符数,失败返回-1,错误原因存于errno 中.

server:#include<stdio.h>#include<string.h>#include<sys/types.h>#include<sys/socket.h>#include<netinet/in.h>#include<unistd.h>#include<stdlib.h>static void usage(char* proc){    printf("Usage: %s [local_ip] [local_port]", proc);}int main(int argc, char* argv[]){    if(argc != 3)    {    usage(argv[0]);    }    //创建套接字    int sock = socket(AF_INET, SOCK_DGRAM,0);    if(sock < 0)    {    perror("sock");    return 1;    }    struct sockaddr_in local;    local.sin_family = AF_INET;    local.sin_port = htons(atoi(argv[2]));    local.sin_addr.s_addr = inet_addr(argv[1]);    //将套接字描述符与IP和端口号进行绑定    if(bind(sock, (struct sockaddr*)&local, sizeof(local)) < 0 )    {    perror("bind");    return 2;    }    struct sockaddr_in client;    char buf[1024];    while(1)    {    socklen_t len = sizeof(client);    //接受客户端发来的信息,将客户端的套接字信息存储于client里    ssize_t s = recvfrom(sock, buf, sizeof(buf)-1, 0, (struct sockaddr*)&client, &len);    if(s > 0)    {            buf[s] = 0;            printf("client [%s] [%d]: %s", inet_ntoa(client.sin_addr), ntohs(client.sin_port),buf);            printf("Server : ");            fflush(stdout);        //从键盘读入信息            int _s = read(0, buf, sizeof(buf)-1);            buf[_s-1] = 0;        //发送信息到客户端        sendto(sock, buf, strlen(buf), 0, (struct sockaddr*)&client, sizeof(client));    }    else    {        perror("recvfrom");        return 3;    }    }    return 0;}

client:#include<stdio.h>#include<string.h>#include<sys/socket.h>#include<netinet/in.h>#include<unistd.h>#include<sys/types.h>static void Usage(char *proc){    printf("Usage %s [server_ip] [server_port]\n", proc);}int main(int argc, char* argv[]){    if(argc != 3)    {    Usage(argv[0]);    return 1;    }    //创建套接字,  注意使用udp套接字编程时应注意模式为SOCK_DGRAM    int sock = socket(AF_INET, SOCK_DGRAM,0);    if(sock < 0)    {    perror("socket");    return 2;    }    //获取服务器套接字信息    struct sockaddr_in server;    server.sin_family = AF_INET;    server.sin_port = htons(atoi(argv[2]));    server.sin_addr.s_addr = inet_addr(argv[1]);    char buf[1024];    int len = sizeof(server);    //用peer接收发送给客户端的远程主机socket信息    struct sockaddr_in peer;    while(1)    {    printf("Please Enter# ");    fflush(stdout);    //从键盘写入内容到缓冲区    ssize_t s = read(0, buf, sizeof(buf)-1);    buf[s] = 0;    socklen_t len1 = sizeof(peer);    if(s >0)    {        printf("server# ");        //将缓冲区内容通过套接字发送到服务器        sendto(sock, buf, strlen(buf), 0, (struct sockaddr*)&server, sizeof(server));        //在从套接字中读取服务器的回应信息        ssize_t _s = recvfrom(sock, buf, sizeof(buf), 0, (struct sockaddr*)&peer, &len1);        if(_s > 0)        {        buf[_s] = 0;        printf("%s\n", buf);        }    }    }    return 0;}

阅读全文
0 0
原创粉丝点击