windows 服务器和客户端可以分别在同一个端口上发起通信并发送命令吗?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5902809/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 16:48:28  来源:igfitidea点击:

Can server and client each initiate communication and send commands on same port?

cwindowsnetworkingclient-server

提问by emge

I have a server and a client app, my server listens on port 10015 and a client which sends commands to that port. Currently both are running on the same machine, but in the future the goal will be to have running on different machines. I have this part working right now.

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

What I need to do next is have my server send commands to my client as well. So I thought I could just re-use my code from my server in my client to listen on a port.

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

But I am not sure that is the best way to do it. Suggestions?

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

When I first tried this, I ran my client app first, and it sent the command to itself. My server app failed to bind to the port (I assume you can only have one process listening on a given port? )

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

Question 1) How can the server send commands to the client? Do I have to create make the server-->client communication on port 10015 and client--->server on a different port like 10016?

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

Question 2) When I send a command from client-->server with send(), what's the best way to receive an ACK to that specific command? If I dont need to send any data back is there a way to just get an ACK automatically when the packet is received by the server?

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

I am currently doing this for every command I want to send :

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

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

not sure if there's a better way to do it? I am expecting to send anywhere between 1-10 commands per sec when my app is busy.

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

thanks, I am new to this networking applications, so any help is greatly appreciated.

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

Edit after reading some comments:
I am using TCP protocol. When I said ACK, I meant I just wanted some acknowledgement from the other app that the command had been received and processed without errors

阅读一些评论后编辑
我正在使用 TCP 协议。当我说 ACK 时,我的意思是我只想从其他应用程序中得到一些确认,即该命令已被接收和处理而没有错误

回答by jedwards

Typically the way this is done is as follows:

通常这样做的方法如下:

  1. The "server" binds a socket to a specified port -- it looks like that'd be 10015 for you.
  2. The "client" uses an ephemeral portfor its outgoing transmissions
  3. If the server is to respond to the client, it sends a message from it's bound port (10015) to the source port of message #2, the ephemeral port.
  1. “服务器”将一个套接字绑定到一个指定的端口——对于你来说,它看起来像是 10015。
  2. “客户端”使用临时端口进行传出传输
  3. 如果服务器要响应客户端,它会从它的绑定端口 (10015) 发送一条消息到消息 #2 的源端口,即临时端口。

On the server:

在服务器上:

If you are using UDP, you can simply copy the sockaddr structure that was set during recvfrom() into the sockaddr structure that you're passing to sendto().

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

If you are using TCP, the socket file descriptor returned by accept() can be used in send() to send response traffic to the client.

如果您使用 TCP,accept() 返回的套接字文件描述符可以在 send() 中用于向客户端发送响应流量。

My favorite C Sockets reference is the free and available online Beej's Guide to Network Programming.

我最喜欢的 C 套接字参考是免费且可用的在线Beej 网络编程指南

回答by Brian Roach

Your question implies that you're using UDP. This requires the client to be listening on a port (vs. two-way communication on a socket in TCP).

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

You are correct, they both can't use the same port. You need to have the client listening on one port, and the server another if they trying to bind to the same interface on a single machine.

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

The answer to Question 2 is ... you're using UDP. You have to explicitly send something back. You should be using recvfrom()in the server; the information for where to send the ack is stored in the struct sockaddr *src_addryou pass in.

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

Edit after re-reading:If you're not trying to use UDP ... you just connect to the server with the client and communicate back and forth over the socket. Your client doesn't listen to anything. The tutorial hereshould help.

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

回答by user207421

They can listen at the same port as long as they are on different hosts.

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

回答by caf

You are correct in that two applications cannot both listen on the same port, on the same address1. If you want your client to have its own listening socket, then it should use a different port number - your suggestion of 10015 for the server and 10016 for the client is fine.

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

However - you likely do notneed the client to have its own listening socket. TCP connections are full-duplex - your server can simply send requests to the client back down the same connection that the client uses to send requests to the server, as long as that connection is still open.

但是-你可能根本没有需要在客户端有自己的监听套接字。TCP 连接是全双工的 - 您的服务器可以简单地将请求发送到客户端,返回到客户端用于向服务器发送请求的同一连接,只要该连接仍然打开。

As for question 2, the best and only way to receieve a useful ACK is to have your application send it itself - normally, after it has executed the command.

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

As for your current method of sending a command, where you setup and tear down a new connection for every command, this is highly inefficient (and also prevents you from using the same connection as a back-channel from the server to the client). Instead, you should keep the connection open and use it to send multiple commands.

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



1. Actually, that's not strictly true - they can, but each incoming connection can be accepted by only one of them. This is not what you want.1. 实际上,严格来说这不是真的——他们可以,但是每个传入的连接只能被其中一个接受。这不是你想要的。