udp通信(udp通信和tcp通信区别)

http://www.itjxue.com  2023-01-27 03:00  来源:未知  点击次数: 

UDP和Socket通信步骤是什么?

UDP Server程序\x0d\x0a1、编写UDP Server程序的步骤\x0d\x0a(1)使用socket()来建立一个UDP socket,第二个参数为SOCK_DGRAM。\x0d\x0a(2)初始化sockaddr_in结构的变量,并赋值。sockaddr_in结构定义:\x0d\x0astruct sockaddr_in {\x0d\x0auint8_t sin_len;\x0d\x0asa_family_t sin_family;\x0d\x0ain_port_t sin_port;\x0d\x0astruct in_addr sin_addr;\x0d\x0achar sin_zero[8];\x0d\x0a};\x0d\x0a这里使用“08”作为服务程序的端口,使用“INADDR_ANY”作为绑定的IP地址即任何主机上的地址。\x0d\x0a(3)使用bind()把上面的socket和定义的IP地址和端口绑定。这里检查bind()是否执行成功,如果有错误就退出。这样可以防止服务程序重复运行的问题。\x0d\x0a(4)进入无限循环程序,使用recvfrom()进入等待状态,直到接收到客户程序发送的数据,就处理收到的数据,并向客户程序发送反馈。这里是直接把收到的数据发回给客户程序。\x0d\x0a\x0d\x0a2、udpserv.c程序内容:\x0d\x0a#include \x0d\x0a#include \x0d\x0a#include \x0d\x0a#include \x0d\x0a#include \x0d\x0a#include \x0d\x0a\x0d\x0a#define MAXLINE 80\x0d\x0a#define SERV_PORT 8888\x0d\x0a\x0d\x0avoid do_echo(int sockfd, struct sockaddr *pcliaddr, socklen_t clilen)\x0d\x0a{\x0d\x0aint n;\x0d\x0asocklen_t len;\x0d\x0achar mesg[MAXLINE];\x0d\x0a\x0d\x0afor(;;)\x0d\x0a{\x0d\x0alen = clilen;\x0d\x0a/* waiting for receive data */\x0d\x0an = recvfrom(sockfd, mesg, MAXLINE, 0, pcliaddr, len);\x0d\x0a/* sent data back to client */\x0d\x0asendto(sockfd, mesg, n, 0, pcliaddr, len);\x0d\x0a}\x0d\x0a}\x0d\x0a\x0d\x0aint main(void)\x0d\x0a{\x0d\x0aint sockfd;\x0d\x0astruct sockaddr_in servaddr, cliaddr;\x0d\x0a\x0d\x0asockfd = socket(AF_INET, SOCK_DGRAM, 0); /* create a socket */\x0d\x0a\x0d\x0a/* init servaddr */\x0d\x0abzero(servaddr, sizeof(servaddr));\x0d\x0aservaddr.sin_family = AF_INET;\x0d\x0aservaddr.sin_addr.s_addr = htonl(INADDR_ANY);\x0d\x0aservaddr.sin_port = htons(SERV_PORT);\x0d\x0a\x0d\x0a/* bind address and port to socket */\x0d\x0aif(bind(sockfd, (struct sockaddr *)servaddr, sizeof(servaddr)) == -1)\x0d\x0a{\x0d\x0aperror("bind error");\x0d\x0aexit(1);\x0d\x0a}\x0d\x0a\x0d\x0ado_echo(sockfd, (struct sockaddr *)cliaddr, sizeof(cliaddr));\x0d\x0a\x0d\x0areturn 0;\x0d\x0a}\x0d\x0a\x0d\x0aUDP Client程序\x0d\x0a1、编写UDP Client程序的步骤\x0d\x0a(1)初始化sockaddr_in结构的变量,并赋值。这里使用“8888”作为连接的服务程序的端口,从命令行参数读取IP地址,并且判断IP地址是否符合要求。\x0d\x0a(2)使用socket()来建立一个UDP socket,第二个参数为SOCK_DGRAM。\x0d\x0a(3)使用connect()来建立与服务程序的连接。与TCP协议不同,UDP的connect()并没有与服务程序三次握手。上面我们说了UDP是非连接的,实际上也可以是连接的。使用连接的UDP,kernel可以直接返回错误信息给用户程序,从而避免由于没有接收到数据而导致调用recvfrom()一直等待下去,看上去好像客户程序没有反应一样。\x0d\x0a(4)向服务程序发送数据,因为使用连接的UDP,所以使用write()来替代sendto()。这里的数据直接从标准输入读取用户输入。\x0d\x0a(5)接收服务程序发回的数据,同样使用read()来替代recvfrom()。\x0d\x0a(6)处理接收到的数据,这里是直接输出到标准输出上。\x0d\x0a\x0d\x0a2、udpclient.c程序内容:\x0d\x0a#include \x0d\x0a#include \x0d\x0a#include \x0d\x0a#include \x0d\x0a#include \x0d\x0a#include \x0d\x0a#include \x0d\x0a#include \x0d\x0a\x0d\x0a#define MAXLINE 80\x0d\x0a#define SERV_PORT 8888\x0d\x0a\x0d\x0avoid do_cli(FILE *fp, int sockfd, struct sockaddr *pservaddr, socklen_t servlen)\x0d\x0a{\x0d\x0aint n;\x0d\x0achar sendline[MAXLINE], recvline[MAXLINE + 1];\x0d\x0a\x0d\x0a/* connect to server */\x0d\x0aif(connect(sockfd, (struct sockaddr *)pservaddr, servlen) == -1)\x0d\x0a{\x0d\x0aperror("connect error");\x0d\x0aexit(1);\x0d\x0a}\x0d\x0a\x0d\x0awhile(fgets(sendline, MAXLINE, fp) != NULL)\x0d\x0a{\x0d\x0a/* read a line and send to server */\x0d\x0awrite(sockfd, sendline, strlen(sendline));\x0d\x0a/* receive data from server */\x0d\x0an = read(sockfd, recvline, MAXLINE);\x0d\x0aif(n == -1)\x0d\x0a{\x0d\x0aperror("read error");\x0d\x0aexit(1);\x0d\x0a}\x0d\x0arecvline[n] = 0; /* terminate string */\x0d\x0afputs(recvline, stdout);\x0d\x0a}\x0d\x0a}\x0d\x0a\x0d\x0aint main(int argc, char **argv)\x0d\x0a{\x0d\x0aint sockfd;\x0d\x0astruct sockaddr_in srvaddr;\x0d\x0a\x0d\x0a/* check args */\x0d\x0aif(argc != 2)\x0d\x0a{\x0d\x0aprintf("usage: udpclient \n");\x0d\x0aexit(1);\x0d\x0a}\x0d\x0a\x0d\x0a/* init servaddr */\x0d\x0abzero(servaddr, sizeof(servaddr));\x0d\x0aservaddr.sin_family = AF_INET;\x0d\x0aservaddr.sin_port = htons(SERV_PORT);\x0d\x0aif(inet_pton(AF_INET, argv[1], servaddr.sin_addr)

回答于?2022-11-17

Socket 通信之 UDP 通信

前段时间,我们在 这篇文章 中谈到了多进程和进程之间的通信方式,主要谈到了本地进程之间使用队列(Queue)进程通信,如果我们要通信的进程不在同一台主机上,我们就无法使用队列进行通信了,这时就需要使用 Socket(套接字)。

Socket 是应用层和传输层之间的一层抽象协议,可以用来进行进程间通信,一般有 UDP 和 TCP 两种通信方式,前者速度稍快,稳定性不好,无法丢包重传。后者速度稍慢一点,但稳定性很好,可以丢包重传。

本文首先介绍使用 Socket 进行 UDP 通信。

使用 Socket 进行 UDP 通信的流程如下:

下面依次进行讲解。

要进行 Socket 通信,我们需要使用 socket 模块,首先需要创建一个 Socket 对象。下面是两种创建方式:

如果我们需要向别的主机发送数据,我们需要改主机的 IP 地址和相应的端口号。在使用 Socket 进行通信时,需要将两个信息写在一元组中,元组的第一项为目标主机 IP 地址,第二项为接受数据的端口号:

其中,IP 地址使用字符串类型,端口号使用数字类型。

如果不绑定端口,每次使用 Socket 时都会由操作系统动态分配一个端口,我们也可以绑定为某个固定的端口。这样做的好处是:如果我们想要接受其他主机的信息,其他主机可以直接向这个端口发送数据,如果使用动态端口的话,发送方并不知道目标端口是什么,因此无法向接收方发送数据。

绑定端口需要使用 Socket 对象的 bind 方法:

bind 方法接受一个元组作为参数,元组的第一项为绑定的 IP 地址,第二项为绑定的端口号。我们可以把第一项指定为本机上的任意一个 IP 地址,也可以设置为一个空字符串 "" ,表示本机上任意合法的 IP 地址。

使用 UDP 套接字协议时,发送数据使用 Socket 对象的 sendto 方法,接受数据使用 Socket 对象的 recvfrom 方法。这两个方法的使用方式如下:

sendto 方法接受两个参数:发送的数据和目标主机的 IP 和端口元组,在 Python3 中,发送的数据应该转为 byte 类型发送,Python2 中可以直接发送字符串。

recvfrom 接受一个参数:本次接受的最大数据尺寸。该方法是阻塞的,只有在接收到数据后才能进行后续的操作。

就像使用文件那样,在使用完套接字后,需要关闭它,调用 close 方法即可。

上面我们介绍了 Socket 的使用方式,下面我们来做一个单工通信的例子(一方负责发送信息,一方负责接收信息)。

我们这里来创建两个文件:用以发送信息的 send.py 和用以接收信息的 recv.py。该实例在虚拟机中模拟(注意将虚拟机设置为桥接模式)。

创建 send.py:

创建 recv.py:

运行结果如下:

上面实现了一个单工通信的例子:一方负责发,一方负责接收。下面我们继续实现一个双工通信的例子,使双方都能够收发消息。

由于接收和发送消息时是使用 while 循环不断轮询的,因此要实现同时发送和接受,我们需要进行多任务处理。

新建一个 msg.py:

这里我们使用 3000 端口发送数据,3001 端口接收数据,运行程序时只需填写目标主机的 IP 地址,就可以进行通信。

运行效果:

我们还可以进行局域网内的广播,只需对 Socket 加上一条设置:

同时,发送广播需要一个广播地址,以及目标主机接受广播的端口:

上面的设置只能给 0 网段的主机发送广播,要想给局域网中所有的主机发送广播,可以这样设置:

下面我们新建一个 send.py 用来发送广播:

新建一个 recv.py 用来接收广播:

运行效果如图:

完。

UDP是什么意思?

UDP 是User Datagram Protocol的简称, 中文名是用户数据报协议,是OSI(Open System Interconnection,开放式系统互联) 参考模型中一种无连接的传输层协议,提供面向事务的简单不可靠信息传送服务,IETF RFC 768是UDP的正式规范。UDP在IP报文的协议号是17。

UDP 用户数据报协议,是一个无连接的简单的面向数据报的运输层协议。UDP不提供可靠性,它只是把应用程序传给IP层的数据报发送出去,但是并不能保证它们能到达目的地。由于UDP在传输数据报前不用在客户和服务器之间建立一个连接,且没有超时重发等机制,故而传输速度很快。

UDP是一种面向无连接的协议,每个数据报都是一个独立的信息,包括完整的源地址或目的地址,它在网络上以任何可能的路径传往目的地,因此能否到达目的地,到达目的地的时间以及内容的正确性都是不能被保证的。

扩展资料:

UDP是面向无连接的通讯协议,UDP数据包括目的端口号和源端口号信息,由于通讯不需要连接,所以可以实现广播发送。

UDP传输数据时有大小限制,每个被传输的数据报必须限定在64KB之内。 UDP是一个不可靠的协议,发送方所发送的数据报并不一定以相同的次序到达接收方。

UDP是面向消息的协议,通信时不需要建立连接,数据的传输自然是不可靠的,UDP一般用于多点通信和实时的数据业务。

参考资料:百度百科-UDP

网线UDP通信(ubuntu设置静态ip)

c++的udp socket,收端要绑定端口号(具体见dell笔记本的sever.cpp)

python的udp scoket,收端要bind自己的ip和port

sudo nano /etc/dhcpcd.conf进入树莓派设置

一、使用命令设置Ubuntu IP地址

1.修改配置文件blacklist.conf禁用IPV6

表示用vi编辑器(也可以用其他编辑器,如gedit)编辑etc文件夹下modprobe.d文件夹中blacklist.conf文档的内容。

注意:只能在root用户模式下才可以修改

在文档最后添加 blacklist ipv6

然后查看修改结果

2.设置网卡eth0的IP地址和子网掩码

将IP地址改为:192.168.2.1,子网掩码改为:255.255.255.0

3.Ubuntu IP设置网关

4.Ubuntu IP设置DNS 修改/etc/resolv.conf,在其中加入nameserver DNS的地址1 和 nameserver DNS的地址2 完成。

5.重启网络服务(若不行,请重启ubuntu:sudo reboot)

6.查看当前IP

二、直接修改Ubuntu IP系统配置文件

Ubuntu IP的网络配置文件是根目录下:/etc/network/interfaces

注意:修改完interfaces文档中的内容后,需要修改/etc/NetworkManager/NetworkManager.conf文档中的managed参数,使之为true,并重启。否则,会提示说“有线网络设备未托管”。

打开后里面可设置DHCP或手动设置静态IP。

前面auto eth0,表示让网卡开机自动挂载eth0。

1. 以DHCP方式配置网卡

编辑文件 /etc/network/interfaces

并用下面的行来替换有关eth0的行:

#The primary network interface - use DHCP to find our address

用下面的命令使网络设置生效:

也可以在命令行下直接输入下面的命令来获取地址sudo dhclient eth0

2. 为网卡配置静态Ubuntu IP地址

编辑文件 /etc/network/interfaces

并用下面的行来替换有关eth0的行:

将eth0的IP分配方式修改为静态分配(static)后,为其制定IP、网关、子网掩码等信息。

将上面的Ubuntu IP地址等信息换成你自己就可以了。

用下面的命令使网络设置生效:

示例:

注意:

若/etc/init.d/networking restart 重启无效,可以直接采用

3. 设定第二个Ubuntu IP地址(虚拟IP地址)

编辑文件/etc/network/interfaces:?

在该文件中添加如下的行:

根据你的情况填上所有诸如address,netmask,network,broadcast和gateways等信息;

用下面的命令使网络设置生效

4. 设置主机名称(hostname)

使用下面的命令来查看当前主机的主机名称:sudo /bin/hostname

使用下面的命令来设置当前主机的主机名称:sudo /bin/hostname newname

系统启动时,它会从/bin/hostname来读取主机的名称。

5. 配置DNS

首先,你可以在/etc/hosts中加入一些主机名称和这些主机名称对应的IP地址,这是 简单使用本机的静态查询。要访问DNS 服务器来进行查询,需要设置/etc/resolv.conf文件,假设DNS服务器的IP地址是192.168.2.2, 那么/etc/resolv.conf文件的内容应为:

search chotim.com

nameserver 192.168.2.2

6.手动重启网络服务:sudo /etc/init.d/networking restart

返回结果如下:

*Reconfiguring network interfaces… [OK]

————————————————

原文链接:

(责任编辑:IT教学网)

更多

推荐服务器空间文章