谁能给个Mac 下使用socket 进行UDP 收发数据的源码

谁能给个Mac 下使用socket 进行UDP 收发数据的源码,第1张

UDP Server程序

1、编写UDP Server程序的步骤

(1)使用socket()来建立一个UDP socket,第二个参数为SOCK_DGRAM。

(2)初始化sockaddr_in结构的变量,并赋值。sockaddr_in结构定义:

struct sockaddr_in {

uint8_t sin_len

sa_family_t sin_family

in_port_t sin_port

struct in_addr sin_addr

char sin_zero[8]

}

这里使用“08”作为服务程序的端口,使用“INADDR_ANY”作为绑定的IP地址即任何主机上的地址。

(3)使用bind()把上面的socket和定义的IP地址和端口绑定。这里检查bind()是否执行成功,如果有错误就退出。这样可以防止服务程序重复运行的问题。

(4)进入无限循环程序,使用recvfrom()进入等待状态,直到接收到客户程序发送的数据,就处理收到的数据,并向客户程序发送反馈。这里是直接把收到的数据发回给客户程序。

2、udpserv.c程序内容:

#include <sys/types.h>

#include <sys/socket.h>

#include <string.h>

#include <netinet/in.h>

#include <stdio.h>

#include <stdlib.h>

#define MAXLINE 80

#define SERV_PORT 8888

void do_echo(int sockfd, struct sockaddr *pcliaddr, socklen_t clilen)

{

int n

socklen_t len

char mesg[MAXLINE]

for()

{

len = clilen

/* waiting for receive data */

n = recvfrom(sockfd, mesg, MAXLINE, 0, pcliaddr, &len)

/* sent data back to client */

sendto(sockfd, mesg, n, 0, pcliaddr, len)

}

}

int main(void)

{

int sockfd

struct sockaddr_in servaddr, cliaddr

sockfd = socket(AF_INET, SOCK_DGRAM, 0)/* create a socket */

/* init servaddr */

bzero(&servaddr, sizeof(servaddr))

servaddr.sin_family = AF_INET

servaddr.sin_addr.s_addr = htonl(INADDR_ANY)

servaddr.sin_port = htons(SERV_PORT)

/* bind address and port to socket */

if(bind(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) == -1)

{

perror("bind error")

exit(1)

}

do_echo(sockfd, (struct sockaddr *)&cliaddr, sizeof(cliaddr))

return 0

}

UDP Client程序

1、编写UDP Client程序的步骤

(1)初始化sockaddr_in结构的变量,并赋值。这里使用“8888”作为连接的服务程序的端口,从命令行参数读取IP地址,并且判断IP地址是否符合要求。

(2)使用socket()来建立一个UDP socket,第二个参数为SOCK_DGRAM。

(3)使用connect()来建立与服务程序的连接。与TCP协议不同,UDP的connect()并没有与服务程序三次握手。上面我们说了UDP是非连接的,实际上也可以是连接的。使用连接的UDP,kernel可以直接返回错误信息给用户程序,从而避免由于没有接收到数据而导致调用recvfrom()一直等待下去,看上去好像客户程序没有反应一样。

(4)向服务程序发送数据,因为使用连接的UDP,所以使用write()来替代sendto()。这里的数据直接从标准输入读取用户输入。

(5)接收服务程序发回的数据,同样使用read()来替代recvfrom()。

(6)处理接收到的数据,这里是直接输出到标准输出上。

2、udpclient.c程序内容:

#include <sys/types.h>

#include <sys/socket.h>

#include <string.h>

#include <netinet/in.h>

#include <stdio.h>

#include <stdlib.h>

#include <arpa/inet.h>

#include <unistd.h>

#define MAXLINE 80

#define SERV_PORT 8888

void do_cli(FILE *fp, int sockfd, struct sockaddr *pservaddr, socklen_t servlen)

{

int n

char sendline[MAXLINE], recvline[MAXLINE + 1]

/* connect to server */

if(connect(sockfd, (struct sockaddr *)pservaddr, servlen) == -1)

{

perror("connect error")

exit(1)

}

while(fgets(sendline, MAXLINE, fp) != NULL)

{

/* read a line and send to server */

write(sockfd, sendline, strlen(sendline))

/* receive data from server */

n = read(sockfd, recvline, MAXLINE)

if(n == -1)

{

perror("read error")

exit(1)

}

recvline[n] = 0/* terminate string */

fputs(recvline, stdout)

}

}

int main(int argc, char **argv)

{

int sockfd

struct sockaddr_in srvaddr

/* check args */

if(argc != 2)

{

printf("usage: udpclient <IPaddress>\n")

exit(1)

}

/* init servaddr */

bzero(&servaddr, sizeof(servaddr))

servaddr.sin_family = AF_INET

servaddr.sin_port = htons(SERV_PORT)

if(inet_pton(AF_INET, argv[1], &servaddr.sin_addr) <= 0)

{

printf("[%s] is not a valid IPaddress\n", argv[1])

exit(1)

}

sockfd = socket(AF_INET, SOCK_DGRAM, 0)

do_cli(stdin, sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr))

return 0

}

运行例子程序

1、编译例子程序

使用如下命令来编译例子程序:

gcc -Wall -o udpserv udpserv.c

gcc -Wall -o udpclient udpclient.c

编译完成生成了udpserv和udpclient两个可执行程序。

2、运行UDP Server程序

执行./udpserv &命令来启动服务程序。我们可以使用netstat -ln命令来观察服务程序绑定的IP地址和端口,部分输出信息如下:

Active Internet connections (only servers)

Proto Recv-Q Send-Q Local Address Foreign Address State

tcp 0 0 0.0.0.0:32768 0.0.0.0:* LISTEN

tcp 0 0 0.0.0.0:111 0.0.0.0:* LISTEN

tcp 0 0 0.0.0.0:6000 0.0.0.0:* LISTEN

tcp 0 0 127.0.0.1:631 0.0.0.0:* LISTEN

udp 0 0 0.0.0.0:32768 0.0.0.0:*

udp 0 0 0.0.0.0:8888 0.0.0.0:*

udp 0 0 0.0.0.0:111 0.0.0.0:*

udp 0 0 0.0.0.0:882 0.0.0.0:*

可以看到udp处有“0.0.0.0:8888”的内容,说明服务程序已经正常运行,可以接收主机上任何IP地址且端口为8888的数据。

如果这时再执行./udpserv &命令,就会看到如下信息:

bind error: Address already in use

说明已经有一个服务程序在运行了。

3、运行UDP Client程序

执行./udpclient 127.0.0.1命令来启动客户程序,使用127.0.0.1来连接服务程序,执行效果如下:

Hello, World!

Hello, World!

this is a test

this is a test

^d

输入的数据都正确从服务程序返回了,按ctrl+d可以结束输入,退出程序。

如果服务程序没有启动,而执行客户程序,就会看到如下信息:

$ ./udpclient 127.0.0.1

test

read error: Connection refused

说明指定的IP地址和端口没有服务程序绑定,客户程序就退出了。这就是使用connect()的好处,注意,这里错误信息是在向服务程序发送数据后收到的,而不是在调用connect()时。如果你使用tcpdump程序来抓包,会发现收到的是ICMP的错误信息。

给你个udp多播例子,广播不是很清楚,呵呵

Imports System.Net

Imports System.Net.Sockets

Imports System.Text

Public Class Form1

Inherits System.Windows.Forms.Form

Dim port As String

Dim ipadd As String

Dim ipend As IPEndPoint

Dim sendudp As New UdpClient()

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) _

Handles Button1.Click

Dim ipadress As IPAddress

ipadress = IPAddress.Parse(TextBox1.Text)

'sendport = Int32.Parse(TextBox2.Text)

'ipend = New IPEndPoint(ipadress, sendport)

Try

sendudp.JoinMulticastGroup(ipadress)

MessageBox.Show("启动完成!")

Catch ex As Exception

MessageBox.Show(ex.Message)

End Try

End Sub

热门频道

首页

博客

研修院

VIP

APP

问答

下载

社区

推荐频道

活动

招聘

专题

打开CSDN APP

Copyright © 1999-2020, CSDN.NET, All Rights Reserved

打开APP

Hilaph

关注

Windows UDP recvfrom 不能阻塞 及 bind 报错的解决办法 原创

2020-07-09 18:44:15

Hilaph

码龄6年

关注

1、正常来说,UDP的recvfrom默认是阻塞的。

可以手动设置是否为阻塞

u_long iMODE = 0//1为非阻塞,0为阻塞

ioctlsocket(udp_cliSocket, FIONBIO, &iMODE)//设置recvfrom是否为阻塞

ioctlsocket的第一个参数为socket套接字。

此处我设置为0,依然会不阻塞。

2、如果bind失败了,也会导致recvfrom不阻塞。

if (bind(udp_cliSocket, (SOCKADDR*)&locAddr, sizeof(locAddr)) == SOCKET_ERROR)

{

printf("UDP bind ERROR :%d\n", WSAGetLastError())

}

如果bind=SOCKET_ERROR时,说明bind失败,通过WSAGetLastError获取报错信息为10049——不能分配请求的地址。

再次检查前面的代码,发现添加本地ip时给错了地址。。。

文章知识点与官方知识档案匹配

网络技能树首页概览

21461 人正在系统学习中

打开CSDN,阅读体验更佳

UDP服务recvfrom函数设置非阻塞_leon_zeng0的博客_recvfrom...

所以,接收情况的判断需要利用recvfrom 的返回值。 新的补充: 不用上面那样复杂,也可以直接用不阻塞标志,如下: ret=recvfrom(sockfd,recvbuff,recvbufflen,MSG_DONTWAIT,( struct sockaddr *) &cliaddr, &clientlen)就是flags标志...

继续访问

recvfrom函数 非阻塞_IO - 同步、异步、阻塞、非阻塞

2 同步非阻塞IO process在NonBlocking IO读recvfrom *** 作的第一个阶段是不会block等待的,如果kernel数据还没准备好,那么recvfrom会立刻返回一个EWOULDBLOCK错误。当kernel准备好数据后,进入处理的第二阶段的时候,process会等待kernel将数据copy...

继续访问

最新发布 UDP socket 设置为的非阻塞模式

非阻塞写的情况下,是采用可以写多少就写多少的策略.与读不一样的地方在于,有多少读多少是由网络发送的那一端是否有数据传输到为标准,但是对于可以写多少是由本地的网络堵塞情况为标准的,在网络阻塞严重的时候,网络层没有足够的内存来进行写 *** 作,这时候就会出现写不成功的情况,阻塞情况下会尽可能(有可能被中断)等待到数据全部发送完毕, 对于非阻塞的情况就是一次写多少算多少,没有中断的情况下也还是会出现write 到一部分的情况.对于一个TCP套接口,内核将从应用进程的缓冲区到该套接口的发送缓冲区拷贝数据。

继续访问

【网络协议】转载:关于TCP与UDP的接收recv和recvfrom

关于TCP与UDP的接收recv和recvfrom 技术标签: 网络协议 计算机网络 1.UDP发包的问题 问:udp 发送(sendto)两次数据,第一次 100字节 ,第二次200字节, 接包方一次recvfrom( 1000 ), 收到是 100,还是200,还是300? 答:UDP是数据报文协议,是以数据包方式,所以每次可以接收100,200,在理想情况下,第一次是无论recvfrom多少都是接收到100。当然,可能由于网络原因,第二个包先到的话,有可能是200了。对可能会由于网络原因乱序,所

继续访问

【提供可能的解决思路】本地编写UDP通信,recvfrom不阻塞,并一直返回-1

【提供可能的解决思路】本地编写UDP通信,recvfrom不阻塞,并一直返回-1 记录一个使用socket库中遇到的问题,最近项目中遇到使用本地udp通信的情况,在编写程序过程中,发现调用recvfrom一直失败,返回-1,错误码10022。 排查了半个下午,终于发现原来是bind函数的问题。 由于在文件开头使用了 using namespace std 导致默认的bind变成了 functional.h中的那个,而不是socket的bind,导致绑定一直没有成功。 解决方案: 1.不要在文件中用 usi

继续访问

socket学习:windows平台用udp模式接收数据,recvfrom函数返回值为-1,但是接收缓冲区中中却有数据

现象:windows平台用udp模式接收数据,recvfrom函数返回值为-1,但是接收缓冲区中中却有数据 方法:用GetLastError(),errno为10040, 错误含义: 一个在数据报套接字上发送的消息大于内部消息缓冲器或其他一些网络限制,或该用户用于接收数据报的缓冲器比数据报小 最后发现原因:接收缓冲buf设置较小,发送方发送的数据超出了接收位置的长度 ...

继续访问

热门推荐 UDP服务recvfrom函数设置非阻塞

基本概念: 方法一:通过fcntl函数将套接字设置为非阻塞模式。 方法二:通过套接字选项SO_RECVTIMEO设置超时。 方法一源码,编译:g++ udp_server.cpp -o server #include #include #include #include #include #include #include #include #include #i

继续访问

关于send和recv在UDP的使用

在socket编程中,包括有连接和无连接两种方式,其流程如下: 有连接: TCP客户端的流程一般是 socket-【bind】-connect-send/recv 无连接: UDP客户端的流程一般是 socket-【bind】-sendto/recvfrom send与sento相比,没有提供对方的地址,在有连接模式中, 连接已经事先建立好,当然不需要每次都提供对方地址。但是,即使在无连接模式中,...

继续访问

C++ UDP通信,recvfrom函数一直堵塞

对于UDP通信中,recvfrom函数一直阻塞的问题,首先要检查发送端……

继续访问

recvfrom不阻塞_一文带你区分阻塞、非阻塞、同步、异步IO

前言:在之前的Redis面试套路拆解的文章[Redis面试套路拆解(一)]中有提到过IO模型,并且IO模型本身也是一个比较容易混淆的高频面试考点,小黑板将在本篇文章帮你理清思路,区分各种IO模型~其实网络上已经有很多博客讲了这个问题,但是总是觉得看完之后还是迷迷糊糊的,感觉大家有点太执着于把这个问题讲的通俗易懂了,经常会举各种各样的例子,比如烧水、去银行办理业务之类的,然而看完之后反倒会产生更多的...

继续访问

SOCKET编程UDP,bind失败

佛了竟然是因为端口号 一直bind失败,找不到原因,没想到端口号的问题,可能是因为端口号已绑定,换个端口号; ret = bind(sServer, (SOCKADDR *)&ServerAddr, sizeof(ServerAddr))std::cout <<retif ( ret== SOCKET_ERROR) { printf("BIND失败!\n")return} ...

继续访问

linux select read阻塞_阻塞&非阻塞&同步&异步之间的关系

一:阻塞与非阻塞阻塞和非阻塞关注的是程序在等待调用结果(消息,返回值)时的状态.阻塞和非阻塞关注的是程序在等待调用结果(消息,返回值)时的状态.阻塞调用是指调用结果返回之前,当前线程会被挂起。调用线程只有在得到结果之后才会返回。非阻塞调用指在不能立刻得到结果之前,该调用不会阻塞当前线程。1.blockingIO(阻塞):1.1:阻塞调用是指调用结果返回之前,当前线程会被挂起。函数只有在得到结果之后...

继续访问

TCP、UDP 通信常用函数send,sendto,recv,recvfrom详解

send函数 int send( SOCKET s,const char FAR *buf,int len,int flags ) 不论是客户还是服务器应用程序都用send函数来向TCP连接的另一端发送数据。 客户程序一般用send函数向服务器发送请求,而服务器则通常用send函数来向客户程序发送应答。 该函数的第一个参数指定发送端套接字描述符; 第二个参数指...

继续访问

非阻塞recvfrom的设置

我想用UDP阻塞模式给硬件设备发包,然后收包。因为网络的问题,经常丢包,也就是发了之后没有响应。这样的话,recvfrom会一直停在那里,死机了一样。 能不能设成超时自动返回,或者其它什么解决办法,谢谢!我不想用非阻塞模式,据说比较耗资源。 //连接超时 //----------------

继续访问

udp_recv(UDP服务器端)

#include <stdio.h>#include <string.h>#include <strings.h>#include <stdlib.h>#include <sys/types.h>#include <sys/socket.h>#include <arpa/inet.h>#define BUFSIZE 64 #define PORT 8888 #define IP “0.0.0.0” int ma

继续访问

linux socket read 阻塞

read函数只是一个通用的读文件设备的接口。是否阻塞需要由设备的属性和设定所决定。一般来说,读字符终端、网络的socket描述字,管道文件等,这些文件的缺省read都是阻塞的方式。如果是读磁盘上的文件,一般不会是阻塞方式的。但使用锁和fcntl设置取消文件O_NOBLOCK状态,也会产生阻塞的read效果。 怎么样以非阻塞的方式从管道中读取数据?因为我用read函数时,如果管道没有数据就会阻塞住

继续访问

如何将UDP的recvfrom函数设置为非阻塞或阻塞超时

本文先介绍我查看了的2篇文章,然后介绍linux 和windows 下的非阻塞设置。最后是非阻塞情况下接收情况的判断。 2篇博文 其实UDP的非阻塞也可以理解成和TCP是一样的,都是通过socket的属性去做。 方法一:通过fcntl函数将套接字设置为非阻塞模式。 方法二:通过套接字选项SO_RECVTIMEO设置超时。 https://blog.csdn.net/daiyudong202...

继续访问

网络编程原理与UDP实现

如何发送数据包? Q:当应用程序产生数据的时候,需要去构造数据包并发送到网络上去,但是由谁负责处理呢? A:现代 *** 作系统负责数据包得构造与发送,应用程序只需提供数据。 当应用程序产生数据时,应用程序将数据交给OS内核,然后在OS内核添加各层的首部,构建好数据包,然后交给网卡,发送到网络中去。 Q:应用程序如何向OS 发送数据呢? A: OS为程序提供了一个接口,即socket API,类似于系统调用函数。 Q:通过socket API,只需要提供数据吗? A:并不,还需要告诉OS 内核,目的端口是什么

继续访问

从另一个线程将recvfrom从阻塞状态唤醒

UDP的多线程程序,一般开一个线程循环调用recvfrom接收消息,当程序中止的时候,如果这个线程阻塞在recvfrom调用,并且没有消息到达,则这个线程无法终止,造成资源泄露等问题。 这里终止这个线程有六种方法: 1. 释放监听的fd,这个是最简单的方法,但是有一点要注意,就是close(fd)系统调用无效,必须要使用shutdown(fd, SHUT_RDWR)来将recvfrom唤醒,因

继续访问

Udp端口绑定失败

前段时间部署业务系统时候,需要用到udp广播的组件都无法启动,报错RuntimeError:bind fail in line of file ../../source/udpnetwork/UdpClient.cpp 段错误 吐核。排查配置文件搞了挺久,最后发现udp广播用的网段,PREFIX不是24,导致广播段不是默认的XX.XX.XX.255。配置文件默认是255,后面改了广播端地址后,绑定就正常了。 ...

继续访问

recvfrom不阻塞

经验分享

写评论

评论

4

点赞

分享

打开CSDN APP阅读体验更佳


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/12035756.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-20
下一篇 2023-05-20

发表评论

登录后才能评论

评论列表(0条)

保存