社区
网络及通讯开发
帖子详情
recvfrom()消息的接收问题
Alaylm
2006-05-01 05:02:33
关于这个recvfrom()函数,现在是不知道什么时候该用它来读取消息,
我在BCB下做个聊天的软件,不想用控件,所以就没有事件了,那么什么时候来让客户端接收消息呢?
不能用按钮来读取吧,
我是新手,请求帮助,苦思好几天了,嘿嘿,
...全文
648
7
打赏
收藏
recvfrom()消息的接收问题
关于这个recvfrom()函数,现在是不知道什么时候该用它来读取消息, 我在BCB下做个聊天的软件,不想用控件,所以就没有事件了,那么什么时候来让客户端接收消息呢? 不能用按钮来读取吧, 我是新手,请求帮助,苦思好几天了,嘿嘿,
复制链接
扫一扫
分享
转发到动态
举报
写回复
配置赞助广告
用AI写文章
7 条
回复
切换为时间正序
请发表友善的回复…
发表回复
打赏红包
铖邑
2006-05-02
打赏
举报
回复
TCP/IP编程基础——超时、多路复用、非阻塞
作者:baoyuhua 时间:2003-02-23 11:11 出处:互联网 责编:chinaitpower
摘要:TCP/IP编程基础——超时、多路复用、非阻塞
在TCP连接中,recv等函数默认为阻塞模式(block),即直到有数据到来之前函数不会返回,而我们有时则需要一种超时机制使其在一定时间后返回而不管是否有数据到来,这里我们就会用到setsockopt()函数:
int setsockopt(int s, int level, int optname, void* optval, socklen_t* optlen);
这里我们要涉及到一个结构:
struct timeval
{
time_t tv_sec;
time_t tv_usec;
};
这里第一个域的单位为秒,第二个域的单位为微秒。
struct timeval tv_out;
tv_out.tv_sec = 1;
tv_out.tv_usec = 0;
填充这个结构后,我们就可以以如下的方式调用这个函数:
setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &tv_out, sizeof(tv_out));(具体参数可以man一下,或查看MSDN)
这样我们就设定了recv()函数的超时机制,当超过tv_out设定的时间而没有数据到来时recv()就会返回0值。
第二个我们要介绍的是多路复用机制,也就是同时监听多个套接字连接。
int select(int n, fd_set* readfds, fd_set* writefds, fd_set* exceptfds, struct timeval* timeout);
这里涉及到了fd_set结构:
typedef struct fd_set
{
u_int fd_count;
int fd_array[FD_SETSIZE];
}
fd_count为fd_set结构中包含的套接字个数,fd_array唯一个int 数组,包含了我们要监听的套接字。
首先我们需要使用FD_SET将我们要监听的套接字添加到fd_set结构中:
fd_set readfd;
FD_SET(fd, &readfd);
然后我们这样调用select函数:
select(max_fd + 1, &readfd, NULL, NULL, NULL);(具体参数可以man一下,或查看MSDN)
FD_ISSET(fd, &readfd);
其中max_fd为我们要监听的套接字中值最大的一个,同时在调用select是要将其加1,readfd即为我们监听的要进行读操作的套接字连接,第三个参数是我们监听的要进行写操作的套接字连接,第四个参数用于异常,而最后一个参数可以用来设定超时,这里同样使用了struct timeval结构,可以实现与前面介绍的同样的效果。这里如果连接进来的话select即返回一个大于零的值,然后我们调用FD_ISSET宏来检测具体是那一个套接字有数据进来(FD_ISSET返回非零值)。
最后介绍的是另一种实现非阻塞的方法,这种方法在有些应用中会起到一定作用,尤其是在select()函数监听的套接字个数超过1024个时(因为fd_set结构在大部分UNIX系统中都对其可以监听的套接字个数作了1024的限制,如果要突破这个限制,必须修改头文件并重新编译内核),我们就不能使用select多路复用机制。
拿recv()函数来说,我们可以这样进行调用:
recv(fd, buf, sizeof(buf), MSG_DONTWAIT);
注意到我们这里采用了MSG_DONTWAIT标志,它的作用是告诉recv()函数如果有数据到来的话就接受全部数据并立刻返回,没有数据的话也是立刻返回,而不进行任何的等待。采用这个机制就可以在多于1024个套接字连接时使用for()循环对全部的连接进行监听。
以上介绍的几点的具体使用方法可以参照我前面的两篇贴子。
铖邑
2006-05-02
打赏
举报
回复
1、关于select的使用,是有点小复杂,我找找看有没有现成的资料贴上来。
2、至于什么时候让它等,很简单,开一个线程不断调用它,是个死循环(除非线程结束)。每时每刻都在等。
3、recvfrom可以是非阻塞,也可以通过调用函数得知是否有数据来临,这个我记不清那个函数了。还有,如果你想用定时调用,也可以试试
Alaylm
2006-05-01
打赏
举报
回复
有没有不让recvfrom不是阻塞的呢,让time控件时时查询,嘿嘿,最笨的方法了吧,希望大哥们能多指点,苦死我了。
Alaylm
2006-05-01
打赏
举报
回复
recvfrom我知道它在等啊,但是我改怎么什么时候让它等呢
Alaylm
2006-05-01
打赏
举报
回复
真是谢谢哥哥们了,大家这么热心我没在,我在陪个朋友,对不起大家了,select()我也想过,看是没用成功,不知道哪里弄错了,反回来的都是-1
事件驱动到是不错哦,能在仔细说说么,
因为BCB的事件为先吧,比如说我在form2的close()中使用这个recvfrom 这个函数吧,得等这个函数接到消息后,才能实现Form2的close()所以有点不太和用,
铖邑
2006-05-01
打赏
举报
回复
想不到大伙五一不休息呀。
楼主的问题有几种答案:
一:windows特有的事件驱动IO,通过调用WSA*函数来完成
二:通过多路复用技术来完成,调用select函数完成
三:启动一个线程,一直接收(调用recvfrom),一般这个socket是阻塞式的,所以如果没有数据到来时,这个调用会休眠,并不会占用多少CPU资源。
先说这么多了,有人抢我机器用,嘿嘿
pp616
2006-05-01
打赏
举报
回复
recvfrom就在等了。
非阻塞
recv
from的设置
系统默认
recv
from函数是阻塞的,这里是非阻塞的设置!!!
windows下UDP组播(多播)发送和
接收
程序
一个简单的C++实现UDP组播发送和
接收
的程序
Linux UDP socket 设置为的非阻塞模式与阻塞模式区别
Linux UDP socket 设置为的非阻塞模式与阻塞模式区别 UDP socket 设置为的非阻塞模式 Len =
recv
from(SocketFD, sz
Recv
Buf, sizeof(sz
Recv
Buf), MSG_DONTWAIT, (struct sockaddr *)&SockAddr,&ScokAddrLen); UDP socket 设置为的阻塞模式 Len =
recv
from(SocketFD, sz
Recv
Buf, sizeof(sz
Recv
Buf), 0, (struct sockaddr *)&SockAddr,&ScokAddrLen); Li
Socket编程例子
Socket编程例子
88-网络编程
接收
函数(
recv
from)
函数原型: int
recv
from(socket s,void *buf,int len,unsigned int flags, struct sockaddr *from,int *fromlen); 函数说明:
接收
一个数据报并保存源地址。 参数说明: s:标识一个已连接套接口的描述字。 buf:
接收
数据缓冲区。 len:缓冲区长度。 flags:调用操作方式,一般设置为0。 from:(可选)指针,用来指定欲
接收
数据的网络地址。 fromlen:(可选)指针,指向from长度值。 返回值:成功则返回接
网络及通讯开发
1,317
社区成员
8,874
社区内容
发帖
与我相关
我的任务
网络及通讯开发
C++ Builder 网络及通讯开发
复制链接
扫一扫
分享
社区描述
C++ Builder 网络及通讯开发
社区管理员
加入社区
获取链接或二维码
近7日
近30日
至今
加载中
查看更多榜单
社区公告
暂无公告
试试用AI创作助手写篇文章吧
+ 用AI写文章