2016-04-19 3 views
-1

Я пытаюсь сделать сервер/клиент с push-уведомлениями.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

'connect()' уже принимает 'const struct sockaddr *' -argument, указывающий удаленный адрес для соединения. – EOF

ответ

0

Вы пытаетесь связать сокет сервера с IP-адресом клиента. Это не сработает. Вы можете привязывать сокет только к локальному адресу. Вы должны использовать bind для входящих соединений, а не для исходящих.

Если вы хотите, чтобы ваш сервер отвечал на запрос от клиента, просто используйте сокет, возвращаемый 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 
Смежные вопросы