UDP通信方式

簡介

一種無鏈接的傳輸層協議,提供面向事務的簡單不可靠信息傳送服務,它一旦把應用的程序發送給網絡層以後不保留數據的備份。可是由於沒有不少安全性的校驗使得它的傳輸速率特別的快。 UDP提供了無鏈接通訊,且不對傳送數據包進行可靠性保證,適合於一次傳輸少許數據,UDP傳輸的可靠性由應用層負責。c++

###所需的結構和方法 *sockaddr_in結構體安全

#include <netinet/in.h>
struct sockaddr_in {
    short            sin_family;   // e.g. AF_INET
    unsigned short   sin_port;     // e.g. htons(3490)
    struct in_addr   sin_addr;     // see struct in_addr, below
    char             sin_zero[8];  // zero this if you want to
};
struct in_addr {
    unsigned long s_addr;  // load with inet_aton()
};
  • sockaddr_in無論是tcp和UDP通信都必然須要的一個結構。AF_INET是internet地址族,包括了tcp、udp什麼的,
  • sin_port 通信的端口
  • sin_addr 保留了通信的IP地址
  • sin_zero 沒有實際意義,只是爲了 跟SOCKADDR結構在內存中對齊 ####socket方法

socket(int socket_family, int socket_type, int protocol);網絡

  • domain

AF_UNIX,AF_LOCAL 本地通信dom

AF_INET IPV4網絡規約socket

AF_INET6 IPV6網絡規約tcp

  • type

SOCK_STREAM 提供可靠的鏈接方式(TCP)函數

SOCK_DGRAM 提供不可靠非鏈接的通信方式(UDP)this

  • protocol

IPPROTO_IP 至關於指定的參數爲零atom

IPPROTO_TCP 代表採用TCP規約指針

IPPROTO_UDP 表示採用UDP規約

####bind方法 bind標準定義是指綁定一個名稱到socket,sockfd是表示一個socket所建立的對象,sockaddr表示是該綁定的地址和socket所指向的地址分配空間大小

int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);

####recvfrom 接收一個數據報並保存源地址

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

  • ssockfd:標識一個已鏈接套接口的描述字。
  • buf:接收數據緩衝區。
  • len:緩衝區長度。
  • flags:調用操做方式。
  • src_addr:(可選)指針,指向裝有源地址的緩衝區。
  • addrlen:(可選)指針,指向from緩衝區長度值。

該函數返回接收的字節數,若是出現錯誤返回-1,假若對方關閉鏈路則返回0;

服務端

socket()->bind()->recvfrom()->sendto()

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#define BUFLEN 512//最大的緩衝長度 
#define PORT 8888//監聽數據的端口
void die(char *s){
    perror(s);
    exit(1);
}
int main(int argc, char const* argv[])
{
    struct sockaddr_in si_me,si_other;
    int s,i,slen=sizeof(si_other),recv_len;
    char buf[BUFLEN];
    //建立一個UDP的socket
    if((s=socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP))==-1){
        die("socket");
    }
    //將這個結構清零
    memset((char *)&si_me,0,sizeof(si_me));

    si_me.sin_family=AF_INET;
    si_me.sin_port=htons(PORT);
    si_me.sin_addr.s_addr=htonl(INADDR_ANY);
    //指定須要綁定的端口
    if(bind(s,(struct sockaddr*)&si_me,sizeof(si_me))==-1){
         die("bind");
    }
    while(1){
        printf("Waiting for data...");
        fflush(stdout);
        //從遠程接收數據,這是一個堵塞的函數,直到接觸到數據爲止
        if((recv_len=recvfrom(s,buf,BUFLEN,0,(struct sockaddr*)&si_other,&slen))==-1)
        {
            die("recvfrom()");
        }
        //打印客戶端的信息及其相關的信息
        printf("Received packet from %s:%d\n",inet_ntoa(si_other.sin_addr),ntohs(si_other.sin_port));
        printf("recv Data:%s\n",buf);
        //將接收到的數據進行發送
        if(sendto(s,buf,recv_len,0,(struct sockaddr*)&si_other,slen)==-1){
            die("sendto()");
        }
        //重置全部的數據
        bzero(&buf,sizeof(buf));
    }
    close(s);//關閉socket
    return 0;
}

Waiting for data...Received packet from 127.0.0.1:64687

recv Data:send data

client端

socket()->sendto()/recvfrom()

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#define SERVER "127.0.0.1"
#define BUFLEN 512//緩衝區的大小
#define PORT 8888//發送數據的端口
void die(char *s){
    perror(s);
    exit(1);
}
int main(int argc, char const* argv[])
{
    struct sockaddr_in si_other;
    int s,i,slen=sizeof(si_other);
    char buf[BUFLEN];
    char message[BUFLEN];
    if((s=socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP))==-1)
    {
        die("socket");
    }
    memset((char *)&si_other,0,sizeof(si_other));
    si_other.sin_family=AF_INET;
    si_other.sin_port=htons(PORT);

    if(inet_aton(SERVER,&si_other.sin_addr)==0){
         fprintf(stderr,"inet_atom() failed\n");
         exit(1);
    }
    while(1){
        printf("Enter message:");
        gets(message);
        //發送數據
        if(sendto(s,message,strlen(message),0,(struct sockaddr *)&si_other,slen)==-1){
            die("sendto()");
        }
        //接收發送的返回消息而且打印
        //再將這個buffer進行清空
        if(recvfrom(s,buf,BUFLEN,0,(struct sockaddr *)&si_other,&slen)==-1){
             die("recvfrom()");
        }
        puts(buf);
        bzero(&buf,sizeof(buf));

    }
    close(s);
    return 0;
}

warning: this program uses gets(), which is unsafe.

Enter message:send data

send data

Enter message:

相關文章
相關標籤/搜索