2016-04-19 401 views
-1

我正在嘗試使服務器/客戶端與推送通知。C服務器連接到客戶端

首先客戶端連接服務器,然後服務器保存客戶端的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"); 

我獲得綁定錯誤:無法分配請求的地址。 我不確定如何在第一次連接後編寫客戶端。這將是傾聽和接受連接,但如果我在客戶端的代碼

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

將IP地址是否與第一個連接相同?

如果有人有另一種解決方案或者更好的,請分享。

+0

爲什麼你使用'bind()的'如果你想在所有連接'()'? – EOF

+0

將sockfd與客戶端的IP地址和端口相關聯。 我學習在C插口,所以也許我錯了,糾正我 – Danick

+0

'連接()'已經採取了'常量結構sockaddr *'-argument指定與連接遠程地址。 – EOF

回答

0

您正在嘗試向服務器套接字到客戶端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