socket编程—UDP套接字
socket编程—UDP套接字
- 一、UDP套接字
- socket函数的参数
- socket()函数返回值
- 1、服务端
- 创建套接字
- 绑定端口
- 提供服务
- 2、客户端
- 创建套接字
一、UDP套接字
IP是标识互联网当中的唯一一台主机
端口号是标识一台主机内的唯一一个进程
两者相加就是标识互联网当中唯一一个进程
整个互联网可以看作一个大的OS,所有在网络上的行为,基本都是在一个大的OS内,进行进程间通信!
所以后续我们IP+端口号=socket
要进行通信,本质:
1、先找到目标主机
2、在找到该主机上的服务(进程)
互联网世界,是一个进程间通信的世界
进程具有独立性,进程间通信的前提工作:先让不同的进程,看到同一份资源。这里的同一份资源是网络!
socket函数的参数
套接字类型:用struct sockaddr *类型表示, 在使用的时候需要强制转化成sockaddr_in; 这样的好处是程序的通用性, 可以接收IPv4, IPv6, 以及UNIX Domain Socket各种类型的sockaddr结构体指针做为参数。
struct sockaddr_in结构体
socket()函数返回值
返回一个文件描述符
1、服务端
创建套接字
作为一个服务器,要不要让客户知道,对应的服务器的地址(ip+port)?必须知道!
服务器的socket信息(ip+port),必须得让客户知道!
一般的服务器port,必须是众所周知(不仅是被人,也可以被各种软件等知道的)的,并且轻易不改变!
绑定端口
bind()函数
提供服务
recvfrom()函数接收对端发来的数据
返回值:
sendto()返回给对端数据
server代码:
#include<iostream>
#include<string>
#include<cerrno>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>//const uint16_t port = 8081;
void Usage(std::string proc)
{std::cout<<"Usage:"<<proc<<"proc"<<std::endl;
}
int main(int argc,char *argv[])
{if(argc != 2){Usage(argv[0]);return -1;}uint16_t port = atoi(argv[1]);//AF_INET 表示 IPv4 地址 OCK_DGRAM(数据报套接字/无连接的套接字)int sock = socket(AF_INET,SOCK_DGRAM,0);//1、创建套接字if(sock < 0)//如果创建失败{std::cerr << "socket create error:" << errno <<std::endl;return 1;}//2、给该服务器绑定端口和ip(需要特殊处理,因为大小端序不一样)struct sockaddr_in local;//创建一个struct sockaddr_in结构的对象//开始填充该对象的字段local.sin_family = AF_INET;local.sin_port = htons(port);//此处的端口号,是我们计算机上的变量,是主机序列,可能需要主机转网络:htons函数//a、需要将人识别的点分十进制,字符串风格IP地址,转化为4字节整数IP//b、也考虑大小端//in_addr_t inet_addr(const char *cp) ;这个函数能完成ab两个工作//坑://云服务器:不允许用户直接bind公网IP,另外,实际正常编写的时候,我们也不会指明IP//local.sin_addr.s_addr = inet_addr("175.178.47.247");//"175.178.47.247"为点分十进制,字符串风格//INADDR_ANY:如果你bind的是明确的IP(主机),意味只有发到该ip主机上的数据//才会交给你的网络进程,但是,一般服务器可能有多张网卡,配置多个ip,我们需要的不是//某个ip上面的数据,我们需要的是,所有发送到该主机,发送到该端口的数据!local.sin_addr.s_addr = INADDR_ANY;//INADDR_ANY零值,相当于默认if(bind(sock,(struct sockaddr*)&local,sizeof(local)) < 0){//(struct sockaddr*)&local需要强转std::cerr << "bind error :" <<errno << std::endl;}//3、提供服务bool quit = false;#define NUM 1024char buffer[NUM];//接收数据缓冲区while(!quit){struct sockaddr_in peer;socklen_t len = sizeof(peer);//注意:我们默认认为通信的数据是双方在互发字符串ssize_t cnt = recvfrom(sock,buffer,sizeof(buffer)-1,0,(struct sockaddr*)&peer,&len);//接收客户端发来的数据,并确认对端是谁if(cnt > 0){buffer[cnt] = 0;std::cout<<"client# " << buffer <<std::endl;//根据用户输入,构建一个新的返回字符串std::string echo_hello = buffer;echo_hello += "....";sendto(sock,echo_hello.c_str(),echo_hello.size(),0,(struct sockaddr*)&peer,len);//返回(发送)数据给对端服务器}else{}}return 0;}
2、客户端
创建套接字
//客户端需要显示的bind嘛?不需要
//a、首先,客户端必须也要有ip和port
//b、但是,客户端不需要显示的bind!一旦显示bind,就必须明确,client要和哪一个port关联
//client指明的端口号,在client端一定有嘛?有可能被占用,被占用导致client无法使用
//server要的是port必须明确,而且不变,但是client只要有就行!一般是由OS自动给你bind()
//就是client正常发送数据的时候,OS会自动给你bind,采用的是随机端口的方式!
client端代码:
#include<iostream>
#include<string>
#include<cerrno>
#include<sys/socket.h>
#include<sys/types.h>
#include<netinet/in.h>
#include<arpa/inet.h>void Usage(std::string proc)
{std::cout<<"Usage: \n\t" <<proc<<"server_ip server_port"<<std::endl;
}
int main(int argc,char *argv[])
{if(argc != 3){Usage(argv[0]);return 0;}//1、创建套接字。打开网咯文件int sock = socket(AF_INET,SOCK_DGRAM,0);if(sock < 0){std::cerr<<"socket error" <<errno<<std::endl;return 1;}//客户端需要显示的bind嘛?不需要//a、首先,客户端必须也要有ip和port//b、但是,客户端不需要显示的bind!一旦显示bind,就必须明确,client要和哪一个port关联//client指明的端口号,在client端一定有嘛?有可能被占用,被占用导致client无法使用//server要的是port必须明确,而且不变,但是client只要有就行!一般是由OS自动给你bind()//就是client正常发送数据的时候,OS会自动给你bind,采用的是随机端口的方式!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]);//存储IP地址//2、使用服务while(1){//a、你的数据从哪里来?std::string message;std::cout<<"输入#";std::cin >> message;//b.你要发给谁?sendto(sock,message.c_str(),message.size(),0,(struct sockaddr*)&server,sizeof(server));//发送数据给对端//此处tmp就是一个“占位符”struct sockaddr_in tmp;socklen_t len = sizeof(tmp);char buffer[1024];ssize_t cnt = recvfrom(sock,buffer,sizeof(buffer),0,(struct sockaddr*)&tmp,&len);if(cnt > 0){//在网络通信中,只有报文大小,或者是字节流中字节的个数,没有C/C++字符串这样的概念buffer[cnt] = 0;std::cout<<"server# " << buffer <<std::endl;}else{}}return 0;
}
注:一些函数的解析为网上截图,如有侵权请联系删除;
socket编程—UDP套接字相关推荐
- JAVA socket编程 Datagram套接字 UDP协议(转)
查看文章 JAVA socket编程 Datagram套接字 UDP协议 2009-05-13 09:35 1 UDP套接字 数据报(Datagram)是网络层数据单元在介质上传输信息的一 ...
- 使用DatagramSocket发送、接收数据(Socket之UDP套接字)
2019独角兽企业重金招聘Python工程师标准>>> 创建一个DatagramSocket实例,并将该对象绑定到指定IP地址.指定端口. 通过上面三个构造器中的任意一个构造器即可创 ...
- 网络编程 UDP套接字
第十二章 UDP套接字 12.1 前言 上一章讲述了TCP通信方式,它是基于流的面向连接的网络通信.UDP是IP协议上的另一种传输协议. TCP和UDP都是端到端的通信协议,都处于TCP/IP网络模型 ...
- JAVA UDP套接字编程
JAVA UDP套接字编程 UDP套接字 无连接 非可靠传输 面向数据报 package com.lius.udp;import java.io.IOException; import java.ne ...
- [python学习] 专题七.网络编程之套接字Socket、TCP和UDP通信实例
很早以前研究过C#和C++的网络通信,参考我的文章: C#网络编程之Tcp实现客户端和服务器聊天 C#网络编程之套接字编程基础知识 ...
- 网络编程(part10)--socket套接字编程之UDP套接字
鄙人学习笔记 文章目录 UDP套接字编程 服务端流程 举个例子 客户端流程 举个例子 TCP套接字和UDP套接字编程区别 UDP套接字编程 服务端流程 创建数据报套接字 sockfd = socket ...
- python套接字编程_Python套接字编程(1)——socket模块与套接字编程
在Python网络编程系列,我们主要学习以下内容: 5. 常见的Python异步编程框架 6. 协程在Python网络编程中的使用 本文介绍Python下的基本套接字编程,主要基于 socket 模块 ...
- Linux IPv6 UDP套接字编程示例
udp ipv6套接字编程和ipv4接口类似,参数略有不同,流程都包括创建套接字.绑定地址.发送等. 下面是一个udp ipv6 demo, 包括创建ipv6套接字.绑定地址和发送数据等. 首先先在l ...
- linux udp套接字编程获取报文源地址和源端口(二)
之前项目中涉及udp套接字编程,其中一个要求是获取客户端发过来报文的端口和ip地址,功能很简单,只是对这一块不很熟.之前使用的方法是通过调用recvmsg这个接口,并通过参数msg里面的msg_nam ...
- TCP和UDP套接字编程
一.Socket简单介绍 如果要在应用层调用传输层的服务,进行相关程序的设计,就要涉及到套接字编程.套接字也称之为Socket,本质上它就是利用传输层提供的一系列Api来进行网络应用程序的设计. 网络 ...
最新文章
- 火爆全网!《算法刷题宝典》资源,免费下载!(含代码数据)
- .Net程序员学用Oracle系列(10):系统函数(中)
- VUE项目中使用this.$forceUpdate();解决页面v-for中修改item属性值后页面v-if不改变的问题
- 3COM小型企业有线局域网方案(三、四、五)
- jq-AJAX 初步了解
- ASP.NET 中执行 URL 重写
- Spring学习大杂烩(待续)
- pytorch dataset读取数据流程_10条PyTorch避坑指南
- 汉字转换成拼音、获取拼音转换
- Jsp和Servlet的关系(通俗易懂)
- spring源码解析专栏导航
- 【转】常见算法在实际项目中的应用
- 基于Springboot实现英语在线学习系统
- MT7658芯片组资料,MT7658处理器参数介绍
- mysql日期vlog
- java设计模式 之适配器模式
- (纪中)2431. 移动奶牛(herding)
- 北斗系统学习—JT808协议用C语言解析
- 记录在苹果mac os系统上使用51单片机仿真软件Proteus
- STM32单片机WIFI物联网可燃气烟雾报警监控系统MQ4MQ2