【问题标题】:C Server connect to ClientC 服务器连接到客户端
【发布时间】:2023-04-09 09:03:02
【问题描述】:

我正在尝试使用推送通知创建服务器/客户端。

首先客户端连接服务器,然后服务器保存客户端的IP地址和端口。在某些时候,服务器需要与客户端连接以发送通知。

这是服务器在接受第一个连接后保存客户端 IP 地址和端口的方式:

char client_ip[INET_ADDRSTRLEN];
int port_c;
// Socket, ..., bind, listen, accept
// Gets Client IP address
struct sockaddr_in* pV4Addr = (struct sockaddr_in*)&cli_addr;
struct in_addr ipAddr = pV4Addr->sin_addr;
inet_ntop( AF_INET, &ipAddr, client_ip, INET_ADDRSTRLEN );
printf("Client ip: %s\n", client_ip);

// Gets Client Port Number
port_c = (int) ntohs(cli_addr.sin_port);
printf("Client port is: %d\n", (int) ntohs(cli_addr.sin_port)); 

// [ ... ]

// Time to send notification to client
bzero((char *) &cli_addr, sizeof(cli_addr));
// Setting IP address and port
cli_addr.sin_family = AF_INET;
bcopy(client_ip, (char *)&cli_addr.sin_addr.s_addr, strlen(client_ip)); 
cli_addr.sin_port = htons(port_c);

// Create socket 
sockfd = socket(AF_INET, SOCK_STREAM, 0);

// Bind socket to the local address 
if(bind(sockfd, (struct sockaddr *) &cli_addr, sizeof(cli_addr)) < 0)
    error("Error bind");

if (connect(sockfd, (struct sockaddr *)&cli_addr, sizeof(cli_addr)) < 0)
    error("ERROR connecting");

我收到绑定错误:无法分配请求的地址。 而且我不确定如何在第一次连接后对 Client 进行编码。它会监听并接受连接,但如果我在客户端代码中这样做

cli_addr.sin_family = AF_INET;
cli_addr.sin_addr.s_addr = INADDR_ANY;
cli_addr.sin_port = htons(port_client);

IP地址会和第一次连接一样吗?

如果有人有其他解决方案或更好的解决方案,请分享。

【问题讨论】:

  • 如果你想connect(),你为什么还要使用bind()
  • 将 sockfd 与 Client 的 IP 地址和端口关联起来。我正在学习 C 中的套接字,所以也许我错了,请纠正我
  • connect() 已经使用了一个const struct sockaddr *-参数来指定要连接的远程地址。
  • 客户端连接到服务器。不是反过来。如果要发送到客户端,请保持它创建的连接打开。

标签: c sockets server connection client


【解决方案1】:

您正在尝试将服务器套接字绑定到客户端 IP。那是行不通的。您只能将套接字绑定到本地地址。您必须将绑定用于传入连接,而不是传出连接。

如果您希望您的服务器响应来自客户端的请求,只需使用accept() 返回的套接字,然后使用此套接字send()

您的服务器代码应如下所示:

SOCKET sock_server = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
struct sockaddr_in sock_local_addr;
memset(&sock_local_addr, 0, sizeof(sock_local_addr));
sock_local_addr.sin_family = AF_INET;
sock_local_addr.sin_port = htons(SERVER_PORT);
sock_local_addr.sin_addr.s_addr = INADDR_ANY;
bind(sock_server, (const struct sockaddr *)&sock_local_addr, sizeof(sock_local_addr));         // bind server socket to any network interface of the server
listen(sock_server, 10);
struct sockaddr_in client_addr;
SOCKLEN_T client_addr_size = sizeof(client_addr);
SOCKET sock_client = accept(sock_server, (struct sockaddr *)&client_addr, &client_addr_size);  // accept incomming connection; this will block until a client connects
recv_size = recv(sock_client, buf_in, sizeof(buf_in), 0);     // receive data from client
send(sock_client, buf_out, sizeof(buf_out), 0);               // send data back to client (buf_out is buffer containing the data to be sent)
shutdown(sock_client, SHUT_RDWR);                             // shutdown connection with client

【讨论】:

    猜你喜欢
    • 2019-06-18
    • 1970-01-01
    • 2012-05-22
    • 2013-05-18
    • 1970-01-01
    • 1970-01-01
    • 2017-05-08
    • 2015-08-21
    • 1970-01-01
    相关资源
    最近更新 更多