能不能同时对一个socket进行读和写的操作!

hzfxjun 2004-12-21 01:32:10
我的程序里面有两个线程,一个是从读的,一个是写的,想问一下可不可以同时对一个socket进行读和写的操作!
...全文
3465 27 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
27 条回复
切换为时间正序
请发表友善的回复…
发表回复
Sander 2005-02-03
  • 打赏
  • 举报
回复
现在我用Block API socket, UDP

我有两个thread, 一个是write thread, 一个是read thread,
问题是当我write 一个大的数据时,怎样保证read不会丢失packet.
askppp 2005-02-02
  • 打赏
  • 举报
回复
不管是否堵塞都是可以的

堵塞时,一个线程读一个线程写

异步时可以在一个线程里处理,也可以受到消息或信号时再创建线程处理
tangrh 2005-02-02
  • 打赏
  • 举报
回复
TCP是全双工啊
lkjx82 2005-02-02
  • 打赏
  • 举报
回复
学习
platinum15 2005-02-02
  • 打赏
  • 举报
回复
请问如何用一个线程监视多个socket
ljhnew 2004-12-23
  • 打赏
  • 举报
回复
如果是采用nonblock模式,你的所谓的同步应该是你自己对于你收发的信息进行同步处理,也就是说你必须用busy loop来接收你的报文,通过判断收到的内容来确定程序的下一步处理,例如:发送报文:00 01 Datapack表示发送数据报文,发送报文:00 02 Messagepack表示发送消息报文,发送报文:00 03 Ctrlpack表示发送控制报文等等。如果你对TCP有所了解,你也可以使用TCP的1byte的带外数据,亦即TCP/IP的捎带技术。
ljhnew 2004-12-22
  • 打赏
  • 举报
回复 1
注意:block在系统调用时,并不是“块”的意思,而是“阻塞”的含义,nonblock是“非阻塞”的意思。
在不同的线程中对同一个SOCKET进行异步的读写操作,原则上说,是可以的,因为你的应用是在用户态,而系统调用已经考虑了不同线程之间对于一定的系统资源访问的同步问题。例如你在LINUX/UNIX中执行系统调用之后判断errno一样(在windows中一般用GetLastError()获得),errno是系统的一个全局变量,但在你的用户态进程/线程中,该变量并保护为局部变量,即系统处理已经给你的调用进行了同步处理(该处理一般是在C/C++ Runtime中实现的,对于其它语言也是类似),对于你执行的如bind、send、recv等都有相同的处理,操作系统核心程序会在任务执行完毕后自动唤醒你的等待进程/线程。所以,一般来说,我们可以用两个线程,一个读,一个写(对于我们来说可以直接称其为全双工吧),这样处理完全可以,并且你可以不必考虑它的同步问题(如前所述,系统已经考虑了同步问题)。
原则上说,在不同线程中对同一个SOCKET进行同样的读或写操作,应该是没有问题的,操作系统核心程序会在任务执行完毕后正确唤醒你的等待进程/线程,对于你的用户态应用可能是随机的,但核心程序有它的处理规则(你可以在UNIX/LINUX中很容易得到它的源码)。不过,对于我们的应用来说,这样做到底意义何在,为了提高程序的效率,尽量减少在过多的线程中执行过多的核心等待调用。
采用TCP(SOCK_STREAM)协议,自然是数据“流”方式,和其它的IO流相似(特别是在UNIX/LINUX系统中),你在程序里处理起来非常方便,你可以把通讯任务交给TCP/IP来处理而可以把精力更多的放在其它你更关系的地方。
zhoujianhei 2004-12-22
  • 打赏
  • 举报
回复
已解决了,谢谢各位

既然SOCKET可以工作在数据流方式,那就让它流吧.
zhoujianhei 2004-12-22
  • 打赏
  • 举报
回复
谢谢 ljhnew

我使用的是block的模式,大小为4096,经过测试是发现你说的现象.
不过block还是不能解决问题(两个块被合成了)
zhoujianhei 2004-12-22
  • 打赏
  • 举报
回复
那么如何实现服务端与客户端同步呢?(nonblock 下)

服务器负责处理数据
{......
}
客户端负责发送数据并得到结果
{
发送...
等待结果(???????)
....}

我对(???????)中是用的GetMessage(...) //结果到达时接收线程抛出指定消息 (出现了很多问题)
不知大家怎么作的?
ljhnew 2004-12-21
  • 打赏
  • 举报
回复
to zhoujianhei,接收到的数据长度为何不是发的长度,数据也不一样呀.(两个发,一个收)

这是有TCP/IP协议决定的,特别是“报文的分组发送”,当IP层在传输中,不能把所有的数据一次传送出去,就会将数据包分组,所以就会导致出你的问题。这只是一个比较简单的解释,如果你希望了解根详细的环节,可以参考一下具体的TCP/IP协议。如在我们普通的以太网上,如果你一次发送1M的数据,而以太网上规定一次的传输最大数据为1500左右(MTU),此时,你很可能在一次recv调用时并不会得到所有的1M数据,你可以用flags=MSG_WAITALL来实现,不过一次接收1M的数据,对于一般的TCP/IP协议栈来说,比较难以处理,所以,你可以采用循环多次调用(最好是block模式)来得到数据。
对于发送数据包来说,也是同样道理,如果你一次发送的数据超过了协议栈的缓冲(特别是在单片机嵌入式系统中),那么发送调用就会给你返回一个实际发送出的数据或直接返回失败。
pclili 2004-12-21
  • 打赏
  • 举报
回复
可以的,你一个线程发,一个线程收,一点问题都没有。
chqu18 2004-12-21
  • 打赏
  • 举报
回复
可以这样做的,读跟写分开就可以了
HunterForPig 2004-12-21
  • 打赏
  • 举报
回复
socket是全双工的,当然可以一边读一边写
Owl_xiang 2004-12-21
  • 打赏
  • 举报
回复
用异步方式,就可以实现同步。但只是宏观上的同步。
hjunxu 2004-12-21
  • 打赏
  • 举报
回复
当然是可以的,但你要保证他们不是同时读,或者同时写。
loucai 2004-12-21
  • 打赏
  • 举报
回复
关注
zhoujianhei 2004-12-21
  • 打赏
  • 举报
回复
接收到的数据长度为何不是发的长度,数据也不一样呀.
(两个发,一个收)

严重关注!
zhangqu_980371 2004-12-21
  • 打赏
  • 举报
回复
就算可以,我也建议你不要这样做。将会给你一些你不希望看到的错误。又何苦呢。
HanZhu1 2004-12-21
  • 打赏
  • 举报
回复
可以,

肯定可以的
加载更多回复(7)

18,363

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 网络编程
c++c语言开发语言 技术论坛(原bbs)
社区管理员
  • 网络编程
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧