UDP数据通讯原理
     UDP数据通讯分服务端(软件)和客户端端:
     服务端(软件)(服务器)先运行,服务端,不需要事先知道客户端IP和port
     客户端(软件)(客户端机器)后运行,一定是客户端先给服务端发包,客户端一定先知道服务端的IP和port
     
 UDP通信实现
     1. 头文件
        #include <sys/types.h>     
        #include <sys/socket.h>
       
     2. 数据结构
        // Internet协议地址结构
        struct sockaddr{
            // 地址的通信领域
            unsigned short int sa_family;  
            
            // ip(4B) 和 port(2B) 
            char sa_data[14];
        };
        
        // 通用数据结构
        struct sockaddr_in {
            unsigned short int sin_family;
            unsigned short int sin_port;     // port
            struct in_addr sin_addr;         // ip地址
        
            // 填充0 (8B)
            unsigned char sin_zero[sizeof (struct sockaddr) -
                       (sizeof (unsigned short int)) -
                       sizeof (unsigned short int) -
                       sizeof (struct in_addr)];
        };

3. 函数

服务端流程
        (1) 创建套接字(创建并且打开套接字)
            /*
             * @param[in] domain 通信领域
             * @li AF_UNIX, AF_LOCAL       unix域套接字通信(本机进程间)
             * @li AF_INET                 IPv4协议通信
             * @li AF_INET6                IPv6协议通信
             * @param[in] type 套接字类型
             * @li SOCK_STREAM 流式套接字
             * @li SOCK_DGRAM 报文套接字
             * @li SOCK_RAW  网络层的协议访问
             * @param[in] protocol 协议标识
             * @li 0 使用默认协议
             *                      
             * @return 文件描述符
             * @li -1 创建失败(错误码见errno)
             */
            int socket(int domain, int type, int protocol);
            
        (2) 绑定ip地址和port(到socket(一定一个进程创建))
            /*
             * @param[in] sockfd socket
             * @param[in] addr 绑定地址(ip地址和port)
             * @param[in] addrlen addr的字节数                      
             * @return @li 0 绑定成功
             * @li -1 创建失败(错误码见errno)
             */
            int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
            
        (3) 接收数据包
            /*
             * @param[in] sockfd socket
             * @param[out] buf  接收数据包的buf
             * @param[in] len buf的字节数 
             * @param[in] flags 0
             * @param[out] src_addr 源地址(IP和Port)
             * @NULL 不接收源地址,此时addrlen也必须为NULL   
             * @param[in | out] addrlen(输入) src_addr缓冲区字节数
             *                      addrlen(输出)  实际地址大小             
             * @return @li >= 0 实际接收的字节数
             * @li -1 创建失败(错误码见errno)
             */
            ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen);
            
        (4) 发送数据包
            /*
             * @param[in] sockfd socket
             * @param[out] buf  发送数据包的buf
             * @param[in] len 发送数据的字节数 
             * @param[in] flags 0
             * @param[out] dest_addr 目标地址(IP和Port)
             * @param[in] addrlen dest_addr字节数            
             * @return @li >= 0 实际发送的字节数
             * @li -1 发送失败(错误码见errno)
             */
            ssize_t sendto(int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *dest_addr, socklen_t addrlen);
            
        (5) 关闭socket
            int close(int sockfd);
        
        客户端流程
        (1) 创建套接字(创建并且打开套接字)
        (2) 发送数据包
        (3) 接收数据包
        (4) 关闭socket
        /*
 * 实现目标:
 * udp客户端
 *
 * 实现步骤:
 * 1. socket
 * 2. 获取用户输入
 * 3. sendto用户输入的内容
 * 4. recvfrom服务器发送过来的内容,并显示
 * 5. close
 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <strings.h>

// net
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

// ./client 192.168.0.249 8888
int main(int argc, const char *argv[])
{
int ret = 0;
int sockfd;
char packet[1024];
struct sockaddr_in server_addr;
struct sockaddr_in peer_addr;
socklen_t addrlen = sizeof(peer_addr);

if (argc < 3){
fprintf(stderr, "Usage: %s <server ip> <server port>\n", argv[0]);
exit(EXIT_FAILURE);
}

// 1. socket
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if (-1 == sockfd){
perror("Fail to socket.");
exit(EXIT_FAILURE);
}

// 填充地址结构
bzero(&server_addr, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(atoi(argv[2]));
server_addr.sin_addr.s_addr = inet_addr(argv[1]);

while (1){
// 2. 获取用户输入
putchar('>');
fgets(packet, sizeof(packet), stdin);
packet[strlen(packet) - 1] = '\0';

// 3. sendto用户输入的内容
ret = sendto(sockfd, packet, strlen(packet), 0, (struct sockaddr *)&server_addr, sizeof(server_addr));
if (-1 == ret){
perror("Fail to sendto");
break;
}

// 4. recvfrom服务器发送过来的内容,并显示
ret = recvfrom(sockfd, packet, sizeof(packet), 0, (struct sockaddr *)&peer_addr, &addrlen);
if (-1 == ret){
perror("Fail to recvfrom.");
break;
}
packet[ret] = '\0';

printf("recv : %s\n", packet);
if (strcmp(packet, "bye") == 0) break;
}

// 5. close
close(sockfd);

return 0;
}

/*
 * 实现目标:
 * udp服务端
 *
 * 实现步骤:
 * 1. socket
 * 2. bind
 * 3. recvfrom客户发送的内容
 * 4. sendto相同的内容客户端
 * 5. close
 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>

// bzero
#include <strings.h>

// net
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

// ./server 192.168.0.249 8888
int main(int argc, const char *argv[])
{
int ret = 0;
int sockfd;
struct sockaddr_in server_addr;
struct sockaddr_in peer_addr;
socklen_t addr_len = sizeof(peer_addr);
char packet[1024];

if (argc < 3){
fprintf(stderr, "Usage: %s <ip> <port>\n", argv[0]);
exit(EXIT_FAILURE);
}

// 1. socket
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if (-1 == sockfd){
perror("Fail to socket.");
exit(EXIT_FAILURE);
}

// 2. bind
bzero(&server_addr, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(atoi(argv[2]));
server_addr.sin_addr.s_addr = inet_addr(argv[1]);

ret = bind(sockfd, (struct sockaddr *)&server_addr, sizeof(struct sockaddr));
if (-1 == ret){
perror("Fail to bind.");
exit(EXIT_FAILURE);
}

while (1) {
// 3. recvfrom客户发送的内容
ret = recvfrom(sockfd, packet, sizeof(packet), 0, (struct sockaddr *)&peer_addr, &addr_len);
if (-1 == ret){
perror("Fail to recvfrom.");
break;
}
packet[ret] = '\0';

printf("----------------------------------------\n");
printf("ip   : %s\n", inet_ntoa(peer_addr.sin_addr));
printf("port : %d\n", ntohs(peer_addr.sin_port));
printf("recv : %s\n", packet);
printf("----------------------------------------\n");

// 4. sendto相同的内容客户端
ret = sendto(sockfd, packet, ret, 0, (struct sockaddr *)&peer_addr, sizeof(struct sockaddr));
if (-1 == ret){
perror("Fail to sendto.");
break;
}

if (strcmp(packet, "bye") == 0) break;
}

// 5. close
close(sockfd);

return 0;
}

udp-->socket通信原理的更多相关文章

  1. Java基础知识强化之网络编程笔记02:Socket通信原理图解

    1. Socket (1)Socket套接字  网络上具有唯一标识的IP地址和端口号组合在一起才能构成唯一能识别的标识符套接字 (2)Socket原理机制:  • 通信两端都有Socket.  • 网 ...

  2. Python Socket通信原理

    [Python之旅]第五篇(一):Python Socket通信原理   python Socket 通信理论 socket例子 摘要:  只要和网络服务涉及的,就离不开Socket以及Socket编 ...

  3. Socket通信原理简介

    Socket通信原理简介 字数1011 阅读1766 评论2 喜欢11 何谓socket 计算机,顾名思义即是用来做计算.因而也需要输入和输出,输入需要计算的条件,输出计算结果.这些输入输出可以抽象为 ...

  4. Socket 通信原理(Android客户端和服务器以TCP&&UDP方式互通)

    转载地址:http://blog.csdn.net/mad1989/article/details/9147661 ZERO.前言 有关通信原理内容是在网上或百科整理得到,代码部分为本人所写,如果不当 ...

  5. PHP的socket通信原理及实现

    对TCP/IP.UDP.Socket编程这些词你不会很陌生吧?随着网络技术的发展,这些词充斥着我们的耳朵.那么我想问: 1.         什么是TCP/IP.UDP?2.         Sock ...

  6. 【Socket通信】关于Socket通信原理解析及python实现

    Socket(套接字)通信{网络通信其实就是Socket间的通信},首先了解下概念:[来源于百度百科] "两个程序通过一个双向的通信连接实现数据的交换,这个连接的一端称为一个socket.& ...

  7. Linux C++ UDP Socket通信实例

    环境:Linux 语言:C++ 通信方式:UDP 服务器端的步骤如下: 1. socket:      建立一个socket 2. bind:          将这个socket绑定在某个端口上(A ...

  8. 【转】Python学习---Socket通信原理以及三次握手和四次挥手详解

    [原文]https://www.toutiao.com/i6566024355082404365/ 什么是Socket? Socket的中文翻译过来就是"套接字".套接字是什么,我 ...

  9. python udp socket通信

    前段时间学习了一下c++的socket通信,但发现那玩意儿比较复杂还是转向python了,下面就是一个简单的udpsocket通信程序,欢迎大佬前来指正 udp聊天 import socket # 创 ...

  10. AF_INET域与AF_UNIX域socket通信原理对比【转】

    转自:https://www.cnblogs.com/lfxiao/p/9672797.html 1.  AF_INET域socket通信过程 典型的TCP/IP四层模型的通信过程. 发送方.接收方依 ...

随机推荐

  1. VC_MFC水波纹控件,开源

    代码和效果图: https://github.com/wjx0912/MfcWaterEffect 集成以下5个文件即可: watereffect\DIB.hwatereffect\DIB.cppwa ...

  2. ASP.NET同页面内【用户控件与父页面】以及【用户控件与用户控件】之间方法调用

    在用户控件中,获取父页面的方法 1:方法没有参数(userInfor()) string userInfor = Convert.ToString(this.Page.GetType().GetMet ...

  3. 【C】 04 - 表达式和语句

    程序的生命力体现在它千变万化的行为,而再复杂的系统都是由最基本的语句组成的.C语句形式简单自由,但功能强大.从规范的角度学习C语法,一切显得简单而透彻,无需困扰于各种奇怪的语法. 1. 表达式(exp ...

  4. Correlation Filter in Visual Tracking系列一:Visual Object Tracking using Adaptive Correlation Filters 论文笔记

    Visual Object Tracking using Adaptive Correlation Filters 一文发表于2010的CVPR上,是笔者所知的第一篇将correlation filt ...

  5. 今天的工作发现了4年前的“bug一枚”

    上午的时候山东公司要求下拨资金160万(因目前系统不能支付个人卡),在下拨单保存的时候系统提示余额不足,我马上看内部存款,结果发现人家还有190万呢,然后就看今天的委托付款单还有下拨单,山东都没有,一 ...

  6. Java多线程-线程的同步与锁

    一.同步问题提出 线程的同步是为了防止多个线程访问一个数据对象时,对数据造成的破坏.例如:两个线程ThreadA.ThreadB都操作同一个对象Foo对象,并修改Foo对象上的数据. package ...

  7. 使用ADD_CUSTOM_COMMAND 添加自定义命令

    e.g. ADD_CUSTOM_COMMAND(           TARGET world_server           COMMAND cp ${CMAKE_SOURCE_DIR}/CMak ...

  8. 使用jQuery清空file文件域的解决方案(转)

    对一个文件域(input type=file)使用了验证后,我们总会希望把文件域中的值给清空了,在IE中,由于安全设置的原因,是不允许更改文件域的值的(也就是不能使用val("") ...

  9. Angular学习

    一.Angular是什么 基于JS的框架,类似JQuery,利用数据绑定和依赖注入实现页面数据的渲染,无需人为写大量的JS,减少了代码量,优美了代码. 二.Angular优缺点 Angular适用与C ...

  10. 70. Implement strStr() 与 KMP算法

    Implement strStr() Implement strStr(). Returns a pointer to the first occurrence of needle in haysta ...