body, table{font-family: 微软雅黑; font-size: 10pt}
table{border-collapse: collapse; border: solid gray; border-width: 2px 0 2px 0;}
th{border: 1px solid gray; padding: 4px; background-color: #DDD;}
td{border: 1px solid gray; padding: 4px;}
tr:nth-child(2n){background-color: #f8f8f8;}

1.1. 使用UDP协议的流程图

UDP通信流程图如下:

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

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

//客户端发数据,系统会自动分配一个端口号,这个端口在你使用的这段时间不会关闭,除非自己close
sendto()
函数原型:
int sendto(int sockfd, const void *msg, int len, unsigned int flags, const struct sockaddr *to, int tolen);
该函数比 send() 函数多了两个参数,
to 表示目地机的IP地址和端口号信息;
tolen 常常被赋值为sizeof (struct sockaddr)。
sendto() 函数也返回实际发送的数据字节长度或在出现发送错误时返回-1。
recvfrom()
函数原型:
int recvfrom(int sockfd, void *buf, int len, unsigned int flags, struct sockaddr *from, int *fromlen);
from 是一个 struct sockaddr 类型的变量,该变量保存连接机的IP地址及端口号。
fromlen 常置为sizeof (struct sockaddr)。
//如果不想获取发送方的信息,可以最后两项直接写NULL
recvfrom() 返回时,fromlen包含实际存入from中的数据字节数。recvfrom()函数返回接收到的字节数或当出现错误时返回-1,并置相应的errno。
udp_server.c udp_client.c
#include "func.h"
int main(int argc,char** argv)
{
        if(argc!=3)
        {
                printf("error args\n");
                return -1;
        }
        int sfd=socket(AF_INET,SOCK_DGRAM,0);
        if(-1==sfd)
        {
                perror("socket");
                return -1;
        }       
        printf("sfd=%d\n",sfd);
        struct sockaddr_in ser;
        memset(&ser,0,sizeof(ser));
        ser.sin_family=AF_INET;
        ser.sin_port=htons(atoi(argv[2])); 
        ser.sin_addr.s_addr=inet_addr(argv[1]);
        int ret;
        ret=bind(sfd,(struct sockaddr*)&ser,sizeof(struct sockaddr));
        if(-1==ret)
        {
                perror("bind");
                return -1;
        }
        struct sockaddr_in client;
        memset(&client,0,sizeof(client));
        int addrlen=sizeof(client);
        char buf[128]={0};
        ret=recvfrom(sfd,buf,sizeof(buf),0,(struct sockaddr*)&client,&addrlen);
//阻塞函数,会卡在这里,直到读到客户端,拿到客户端IP和端口;
        if(-1==ret)
        {
                perror("recvfrom");
                return -1;
        }
        printf("client ip =%s,port =%d\n",inet_ntoa(client.sin_addr),ntohs(client.sin_port));
        printf("recv buf =%s\n",buf);
        ret=sendto(sfd,"I am server",11,0,(struct sockaddr*)&client,sizeof(struct sockaddr));
        if(-1==ret)
        {
                perror("sendto");
                return -1;
        }
        close(sfd);
        return 0;
}
#include "func.h"
int main(int argc,char** argv)
{
        if(argc!=3)
        {
                printf("error args\n");
                return -1;
        }
        int sfd=socket(AF_INET,SOCK_DGRAM,0);
        if(-1==sfd)
        {
                perror("socket");
                return -1;
        }       
        printf("sfd=%d\n",sfd);
        struct sockaddr_in ser;
        memset(&ser,0,sizeof(ser));
        ser.sin_family=AF_INET;
        ser.sin_port=htons(atoi(argv[2]));
        ser.sin_addr.s_addr=inet_addr(argv[1]);
        int ret;
        ret=sendto(sfd,"I am client",11,0,(struct sockaddr*)&ser,sizeof(struct sockaddr));
        if(-1==ret)
        {
                perror("sendto");
                return -1;
        }
        struct sockaddr_in client;
        memset(&client,0,sizeof(client));
        int addrlen=sizeof(client);
        char buf[128]={0};
        ret=recvfrom(sfd,buf,sizeof(buf),0,(struct sockaddr*)&client,&addrlen);
//不想获取发送方发过来的数据就直接最后两个参数写NULL
        if(-1==ret)
        {
                perror("recvfrom");
                return -1;
        }
        printf("server ip =%s,port =%d\n",inet_ntoa(client.sin_addr),ntohs(client.sin_port));
        printf("recv buf =%s\n",buf);
        close(sfd);
        return 0;
}
func.h
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>

                                          
注意:操作系统的UDP接收流程如下:收到一个UDP包后,验证没有错误后,放入一个包队列中,队列中的每一个元素就是一个完整的UDP包。当应用程序通过recvfrom()读取时,OS把相应的一个完整UDP包取出,然后拷贝到用户提供的内存中,物理用户提供的内存大小是多少,OS都会完整取出一个UDP包。如果用户提供的内存小于这个UDP包的大小,那么在填充满内存后,UDP包剩余的部分就会被丢弃,以后再也无法取回。
这与TCP接收完全不同,TCP没有完整包的概念,也没有边界,OS只会取出用户要求的大小,剩余的仍然保留在OS中,下次还可以继续取出。

(UDP)socket编程的更多相关文章

  1. tcp/udp socket编程异同

    一.TCP与UDP的区别 基于连接与无连接 对系统资源的要求(TCP较多,UDP少) UDP程序结构较简单 流模式与数据报模式 TCP保证数据正确性,UDP可能丢包 TCP保证数据顺序,UDP不保证 ...

  2. Linux网络编程:UDP Socket编程范例

    TCP协议提供的是一种可靠的,复杂的,面向连接的数据流(SOCK_STREAM)传输服务,它通过三段式握手过程建立连接.TCP有一种"重传确认"机制,即接收端收到数据后要发出一个肯 ...

  3. Go语言TCP/UDP Socket编程

    1. TCP编程 TCPClient // TCPClient project main.go package main import ( "fmt" "net" ...

  4. tcp udp socket编程

    http://blog.csdn.net/ns_code/article/details/14128987

  5. iOS Socket编程-C语言版(UDP)

    . UDP Socket编程 先讲一讲UDP编程,因为比TCP要简单多了.首先,我们需要明白UDP是用户数据报协议,英文名为User Datagram Protocol,它是面向无连接的. 注意:So ...

  6. Java Socket编程题库

    一.    填空题 ___ IP地址____用来标志网络中的一个通信实体的地址.通信实体可以是计算机,路由器等. 统一资源定位符URL是指向互联网"资源"的指针,由4部分组成:协议 ...

  7. 如何为可扩展系统进行Java Socket编程

    从简单I/O到异步非阻塞channel的Java Socket模型演变之旅 上世纪九十年代后期,我在一家在线视频游戏工资工作,在哪里我主要的工作就是编写Unix Unix Berkley Socket ...

  8. Linux编程之UDP SOCKET全攻略

    这篇文章将对linux下udp socket编程重要知识点进行总结,无论是开发人员应知应会的,还是说udp socket的一些偏僻知识点,本文都会讲到.尽可能做到,读了一篇文章之后,大家对udp so ...

  9. 8.1 Socket编程

    8.1 Socket编程 在很多底层网络应用开发者的眼里一切编程都是Socket,话虽然有点夸张,但却也几乎如此了,现在的网络编程几乎都是用Socket来编程.你想过这些情景么?我们每天打开浏览器浏览 ...

  10. 【转】Linux编程之UDP SOCKET全攻略

    转自:http://www.cnblogs.com/skyfsm/p/6287787.html?utm_source=itdadao&utm_medium=referral 这篇文章将对lin ...

随机推荐

  1. Cat VS Dog---hdu3829(最大独立集)

      题目链接 题意:有n只猫,有m只狗.现在有P个学生去参观动物园.每个孩子有喜欢的动物和不喜欢的动物.假如他喜欢猫那么他就一定不喜欢狗(反之亦然). 如果一个孩子喜欢一个动物,那么这个动物不会被移除 ...

  2. 点击劫持漏洞解决( Clickjacking: X-Frame-Options header missing)

    点击劫持漏洞 X-Frame-Options HTTP 响应头, 可以指示浏览器是否应该加载一个 iframe 中的页面. 网站可以通过设置 X-Frame-Options 阻止站点内的页面被其他页面 ...

  3. mysql误删表,无备份

    mysql误删表,无备份 1.操作步骤:https://blog.csdn.net/u011277123/article/details/78018513?tdsourcetag=s_pctim_ai ...

  4. 在Marathon 上部署 cAdvisor + InfluxDB + Grafana Docker监控

    关于 Docker 容器的监控,google cAdvisor 是个很好的工具,但是它默认只显示实时数据,不储存历史数据.为了存储和显示历史数据.自定义展示图,可以把将cAdvisor与InfluxD ...

  5. http之请求方法

    根据HTTP标准,HTTP请求可以使用多种请求方法.HTTP1.0定义了三种请求方法: GET, POST 和 HEAD方法.HTTP1.1新增了五种请求方法:OPTIONS, PUT, DELETE ...

  6. ACM-ICPC 2018 沈阳赛区网络预赛 Solution

    A. Gudako and Ritsuka 留坑. B. Call of Accepted 题意:定义了一种新的运算符$x d y$ 然后给出中缀表达式,求值 思路:先中缀转后缀,然后考虑如何最大如何 ...

  7. uva1401 dp+Trie

    这题说的是给了一个长的字符串长度最大300000,又给了4000个单词 单词的长度不超过100.计算这个字符串能组成多少种不同单词的组合,求出方案总数.dp[i]以第i个字符为开始的字符串能有多少种的 ...

  8. tcpdump 的正确食用方法

    目录 tcpdump 使用笔记 重要报文头 字段表 ip header tcp header 基础使用 高级版本 指定ttl(通过ttl能够确定系统的类型) tcpdump 使用笔记 重要报文头 字段 ...

  9. BZOJ 2756 【SCOI2012】 奇怪的游戏

    题目链接:奇怪的游戏 一开始这道题想岔了……想到黑白染色后对总格子数按奇偶性分类讨论,然后没发现奇数个格子的可以直接解方程…… 首先可以发现每次操作是给相邻的两个格子权值加一,因此我们把棋盘黑白染色后 ...

  10. 读写 Excel 工作表

    导入诸如 CSV 之类文本格式的数据的优点是不需要依靠某些特定软件来读取数据,并且文件具有可读性,即软件中性.然而,它的缺点也很明显——我们不能直接对文本编辑器中的数据执行计算操作,因为这些内容是纯文 ...