使用C进行套接字编程中的双向通信

12

我在套接字编程中有一个小疑问。我能够将客户端的数据发送到服务器并由服务器处理数据。我想将处理后的数据发送回客户端。因此,我是否可以使用同一套接字"write"数据返回给客户端?我的意思是,服务器在接受连接和接收数据之前侦听某个端口,那么同样地,我需要让客户端侦听其他端口(将其绑定到其他套接字),并使我的服务器连接到该套接字并将数据传输回来。任何示例、说明或参考资料都将不胜感激。非常感谢。


我也遇到了这个问题。你得到答案/示例代码了吗? - iammilind
5个回答

16

首先,查看Beej的网络编程指南

服务器/客户端连接的基本流程如下:

  • 服务器通过给定的套接字在固定端口上进行listen()监听。
  • 客户端通过connect()连接到服务器端口;客户端获得一个套接字。
  • 服务器通过accept()接受连接,并返回一个用于连接的套接字。
  • (服务器继续使用原始套接字在原始端口上监听.)

对于与客户端的特定连接,服务器将使用在接受传入连接时获取的新套接字进行write()。一个繁忙的服务器将拥有许多套接字,但它只需要bind()到一个端口上。所有连接都进入该端口,但操作系统的网络协议栈会将数据分离并在连接特定的套接字上可用。


1
更好的说法是,accept() 返回 一个新的套接字以进行连接。 - Karoly Horvath
使其在连接特定的套接字上可用。仍然有一个服务器端口号,但操作系统根据客户端IP+端口和服务器IP+端口(这4个和协议类型(TCP/UDP/...))对传入的数据包进行多路复用,从而使连接唯一。 - Karoly Horvath
我的意思是——弗洛伊德笔误 :-) 谢谢! - Kerrek SB
@KerrekSB,我是偶然点赞的。这并没有回答原问题。现在我也遇到了同样的问题。我能够从(虚拟)服务器向(虚拟)客户端发送数据。但是当我尝试从客户端发送数据时,什么都不会发生。你能否对此进行更详细的解释? - iammilind
1
@iammilind:当服务器和客户端建立连接时,它们都会拥有一个打开的文件描述符。它们可以随意从文件描述符中读取和写入数据。 - Kerrek SB

13

你不需要一个新的套接字。

套接字是一种双工连接,您可以在两个方向发送数据,甚至可以从一个方向关闭套接字(不想再写了),但仍然可以从另一个方向发送数据。


3

从技术上来说,这是正确的,socket是双工的,你可以将数据发送到你读取数据的同一个socket:

   SOCKET s = socket()
   ... //Connect
   int size = receive(s,...);
   //make response 
   send(s, ...);

但是在实践中,这取决于你要做什么。如果你遇到以下情况,就可能会挂起套接字:

  1. 进程1通过一个发送操作向套接字发送非常大的数据(<100K)

  2. 进程2通过分部接收来自1的数据,并向1发送小数据包(〜20b)。 它不是确认,而是一些外部事件。 情况进入挂起状态,2的发送缓冲区已满,并停止向1发送确认。 2和1在其发送操作中挂起,形成死锁。 在这种情况下,我建议使用两个套接字。一个用于读取,另一个用于写入。


3

您的套接字是双向的,因此无需创建另一个套接字。除非您使用某种中间件,例如Pub/Sub,否则无需创建另一个套接字以实现双向通信。


1
(晚回答,主要是为了帮助其他需要帮助的人)
我最近发布了一个示例客户端/服务器应用程序,紧密遵循Beej的网络编程指南(也被Kerrek SB在他的答案中推荐)。如果你正在寻找一个简单的客户端/服务器通信的工作示例,也许这会有所帮助:

https://github.com/countvajhula/dummyclientserver

特别是,在服务器接受了客户端的连接之后,您的客户端不需要设置单独的侦听套接字来接收来自服务器的数据--服务器可以在同一个套接字上向客户端发送数据。

@Andrew 嗯,我能理解你的感受,你在某种程度上是正确的 - 我回答这个问题的目的确实是为了让我的示例应用程序更加可见,同时也回答了这个具体的问题(尽管我仍然回答了)。但我的观点是,当我学习这些东西时,这个应用程序对我来说非常有用,我希望它对其他处于类似阶段的人也是如此,因为它涵盖了基本客户端/服务器通信的方方面面。此外,这个问题确实要求提供“示例”。 - mindthief
1
请务必仔细阅读自我推广的常见问题解答,并注意你之前两篇自我推广的帖子所发生的事情。我没有将这篇标记为垃圾邮件,因为至少它在文本中某处包含了一个答案。 - Andrew Barber
重要的不是你从中“获得”了什么,而是Stack Overflow不是一个链接到“东西”的存储库,而是一个自包含问题答案的存储库。在站点外推广某些东西并不能达到这个目的。这就是为什么这个答案保留下来而其他答案被删除的原因。请注意,如果您继续包含太多指向您“示例”的链接,它们仍将被删除。您可以同意或不同意,但当它说“产品”时,您发布的内容绝对算数 - Andrew Barber
这是自我推广。这是你的项目/创作。这不是一些无关第三方在推广它,这是稍微有点不同的事情。 - Andrew Barber
谁在宣传这个并不重要。它是相关的、有用的话题。无论如何,我不想为了争辩而和你开展一场火药味十足的战争。让我们和平相处吧。 - mindthief
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接