【问题标题】:Can server and client each initiate communication and send commands on same port?服务器和客户端可以在同一个端口上分别发起通信和发送命令吗?
【发布时间】:2011-05-05 19:02:11
【问题描述】:

我有一个服务器和一个客户端应用程序,我的服务器侦听端口 10015 和一个向该端口发送命令的客户端。目前两者都在同一台机器上运行,但未来的目标将是在不同的机器上运行。我现在有这部分工作。

接下来我需要做的是让我的服务器也向我的客户端发送命令。所以我想我可以在我的客户端重新使用我的服务器上的代码来监听端口。

但我不确定这是最好的方法。建议?

当我第一次尝试这个时,我首先运行了我的客户端应用程序,然后它把命令发送给了自己。我的服务器应用未能绑定到端口(我假设您只能让一个进程监听给定端口?)

问题 1) 服务器如何向客户端发送命令?我是否必须在端口 10015 上创建服务器--> 客户端通信,并在 10016 等不同端口上创建客户端--> 服务器?

问题 2) 当我使用 send() 从客户端-> 服务器发送命令时,接收对该特定命令的 ACK 的最佳方式是什么?如果我不需要发回任何数据,有没有办法在服务器收到数据包时自动获取 ACK?

我目前正在为我要发送的每个命令执行此操作:

create socket()
conenct() to socket
send() packet
then call recv() to receive any data 
then shutdown() connection
and closesocket() at end

不确定是否有更好的方法?当我的应用程序繁忙时,我希望每秒发送 1-10 个命令。

谢谢,我是这个网络应用程序的新手,因此非常感谢任何帮助。

阅读一些 cmets 后编辑
我正在使用 TCP 协议。当我说 ACK 时,我的意思是我只是想从其他应用程序中确认命令已被接收并正确处理

【问题讨论】:

  • 是的,只有一个进程可以同时绑定和监听一个TCP地址+端口。所以你有两个程序想要交换数据?除非我错过了什么,否则您可以使用一个套接字并双向发送数据。
  • 你能说明你有什么协议吗?如果这确实是 TCP,那么您无需发送和接收 ACK 消息。
  • 你不需要关闭连接,如果你打开一个 TCP/IP 网络套接字然后让它保持打开状态。服务器和客户端可以来回发送彼此的消息。你提到ACK,你会写HL7接口吗?
  • 我正在使用 TCP 协议。当我说 ACK 时,我的意思是我只是想从另一个应用程序中确认命令已被接收并正确处理。

标签: c windows networking client-server


【解决方案1】:

通常这样做的方式如下:

  1. “服务器”将一个套接字绑定到一个指定的端口——它看起来对你来说是 10015。
  2. “客户端”使用ephemeral port 进行传出传输
  3. 如果服务器要响应客户端,它会从其绑定端口 (10015) 将消息发送到消息 #2 的源端口,即临时端口。

在服务器上:

如果您使用的是 UDP,您可以简单地将在 recvfrom() 期间设置的 sockaddr 结构复制到您传递给 sendto() 的 sockaddr 结构中。

如果你使用的是TCP,accept()返回的socket文件描述符可以在send()中用来向客户端发送响应流量。

我最喜欢的 C Sockets 参考是免费的,可在线获得 Beej's Guide to Network Programming

【讨论】:

    【解决方案2】:

    您的问题暗示您使用的是 UDP。这要求客户端在一个端口上监听(与 TCP 中套接字上的双向通信相比)。

    你是对的,他们都不能使用同一个端口。如果客户端尝试绑定到单台机器上的同一个接口,您需要让客户端监听一个端口,让服务器监听另一个端口。

    问题 2 的答案是……您使用的是 UDP。你必须明确地发回一些东西。您应该在服务器中使用recvfrom();发送 ack 的信息存储在您传入的 struct sockaddr *src_addr 中。

    重读后编辑:如果您不尝试使用 UDP ...您只需使用客户端连接到服务器并通过套接字来回通信。你的客户什么都不听。教程here 应该会有所帮助。

    【讨论】:

      【解决方案3】:

      只要它们在不同的主机上,它们就可以在同一个端口上监听。

      【讨论】:

        【解决方案4】:

        您是正确的,因为两个应用程序不能同时在同一端口上侦听同一地址1。如果您希望您的客户端拥有自己的侦听套接字,那么它应该使用不同的端口号 - 您建议服务器使用 10015,客户端使用 10016 就可以了。

        但是 - 您可能需要客户端拥有自己的侦听套接字。 TCP 连接是全双工的 - 只要该连接仍处于打开状态,您的服务器就可以简单地将请求发送到客户端,返回客户端用来向服务器发送请求的同一连接。

        关于问题 2,接收有用 ACK 的最佳且唯一的方法是让您的应用程序自己发送它 - 通常是在它执行命令之后。

        至于您当前发送命令的方法,即为每个命令设置和断开新连接,这是非常低效的(并且还阻止您使用相同的连接作为从服务器到客户)。相反,您应该保持连接打开并使用它来发送多个命令。


        1。实际上,严格来说这不是真的 - 他们可以,但每个传入的连接只能被其中一个接受。这不是你想要的。

        【讨论】:

        • '并且还可以防止......'不,它没有。
        • @EJP:当然可以——如果客户端在收到对其命令的响应后立即关闭套接字,那么稍后当服务器要发送命令时它不会打开。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2023-03-08
        • 1970-01-01
        • 2021-03-05
        • 1970-01-01
        • 2017-08-20
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多