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. Python开发【Django】:模板语言

    排序 1.forloop.counter 表示循环的次数,它从1开始计数,第一次循环设为1 {% for item in todo_list %} <p>{{ forloop.counte ...

  2. cocos2d 特效

    一.特效概念 特效是让精灵(CCSprite)执行某种特殊的效果.其实,特效也是一种动画! 但是,为什么要把特效与动画区分呢?因为,特效是基于网格属性来进行的. 如何区分动画与特效?简单的将,当使用到 ...

  3. Linux内核之vmlinux与vmlinuz

    因为是初次系统的学习Linux内核,过程中遇到了一些常常出现的名词.似曾相识,但对他们的含义又不是非常清楚.因此,将搜索到的内容进行一下汇总. 1.vmlinux   vmlinux是一个包括linu ...

  4. EasyUI Progressbar 进度条

    通过 $.fn.progressbar.defaults 重写默认的 defaults. 进度条(progressbar)提供了一种显示长时间操作进度的反馈.进度可被更新以便让用户知道当前正在执行的操 ...

  5. MessageBox.show显示窗口在最上层

    C#中使用MessageBox.Show();有时候会被主窗口挡住而看不到.使用如下语句则可以使其显示在最上层. MessageBox.Show("MessageBox显示窗口在最上层了吗? ...

  6. js文件被浏览器缓存

    如果修改了js文件中的js代码,发布代码到线上后.用户的浏览器使用的还是原来js缓存.所以并不会马上生效. 如何才能让浏览器使用最新的js文件呢? 我去看了一下淘宝,发现也是这样一种方式额,不知道对不 ...

  7. 892. Surface Area of 3D Shapes

    问题 NxN个格子中,用1x1x1的立方体堆叠,grid[i][j]表示坐标格上堆叠的立方体个数,求这个3D多边形的表面积. Input: [[1,2],[3,4]] Output: 34 思路 只要 ...

  8. Float类型出现舍入误差的原因(round 取位)

    在练习时,输入如下代码: 结果不准确. 原因:https://blog.csdn.net/bitcarmanlee/article/details/51179572 浮点数一个普遍的问题就是在计算机的 ...

  9. P1052 过河(离散化+dp)

    P1052 过河 dp不难,重点是要想到离散化. 石子个数$<=100$意味着有大量空间空置,我们可以缩掉这些空间. 实现的话自己yy下就差不多了. #include<iostream&g ...

  10. Example解析

    本文总结自:https://github.com/abel533/Mapper/wiki/6.example,旨在提供一些基本概念上的解释 Example类用于条件查询,以代替冗长的"sel ...