Client/server широковещательный запрос
Создаю программу клиент сервер, в которой при запуске сервера в аргументах можно указать порт и максимальное количество подключений. В клиенте при его запуске нужно реализовать отправку широковещательного запроса с чем и возникли трудности. Мне нужно что бы клиент отправлял широковещательный запрос для уведомления сервера о том что он есть. код сервера :
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#define DEFPORT 5000
#define DEFNUM 3
typedef struct options {
int port;
int number;
} info_t;
/*
* ip port
* number of connection for work
*/
static int server(int port, int nmax)
{
int sock;
struct sockaddr_in server;
int mysock;
char buff[1024];
int rval;
int n = 0;
/* Create socket */
sock = socket (AF_INET, SOCK_STREAM, 0);
if (sock < 0) {
perror("create socet failure");
return -1;
}
server.sin_family = AF_INET;
server.sin_addr.s_addr = INADDR_ANY;
server.sin_port = htons(port);
/* Call bind */
if (bind(sock, (struct sockaddr *)&server, sizeof(server))) {
perror("bind failed");
return -1;
}
/*listen*/
listen(sock, 5);
/* Accept */
while (n < nmax) {
mysock = accept(sock, (struct sockaddr *) 0, 0);
if (mysock == -1) {
perror("accept failed");
} else {
memset(buff, 0, sizeof(buff));
if ((rval = recv(mysock, buff, sizeof(buff), 0)) < 0) {
perror("reading stream message error");
} else if (rval == 0) {
printf("Ending connection\n");
} else {
printf("MSG: %s\n",buff);
printf("Got message (rval = %d)\n", rval);
n++;
}
close(mysock);
}
}
return 0;
}
static void parse_args(int argc, char *argv[], info_t *info)
{
int rez = 0;
int p = info->port, n = info->number;
while ((rez = getopt(argc, argv, "p:n:h")) != -1) {
switch (rez) {
case 'p':
p = atoi(optarg);
if (p <= 0 || p >= 65535) p = DEFPORT;
break;
case 'n':
n = atoi(optarg);
if (n <= 0) n = DEFNUM;
break;
case 'h':
printf("\nUsage:\n\t-p PORT; -n NUMBER\n\n");
exit(0);
default:
break;
}
}
info->port = p;
info->number = n;
}
int main (int argc, char *argv[])
{
info_t info = {
.port = DEFPORT,
.number = DEFNUM
};
parse_args(argc, argv, &info);
server(info.port, info.number);
return 0;
}
код клиента:
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#define DATA "HI MANN"
/*
* ip mask
* ip port
* message
*/
int main (int argc, char *argv[])
{
int sock;
struct sockaddr_in server;
struct hostent *hp;
char buff[1024];
char *ip = "127.0.0.1";
int port = (5000);
if (argc > 1){
ip = argv[1];
}
sock = socket (AF_INET, SOCK_STREAM, 0);
if(sock < 0){
perror("не удалось создать сокет");
return -1;
}
server.sin_family = AF_INET;
printf("send to: %s\n", ip);
hp = gethostbyname(ip);
if(hp == 0){
perror("gethostbyname failed");
close(sock);
return -1;
}
memcpy(&server.sin_addr,hp->h_addr, hp->h_length);
server.sin_port = htons (port);
if(connect (sock,(struct sockaddr *) &server, sizeof(server)) < 0){
perror("connect failed");
close(sock);
return -1;
}
if(send(sock,DATA, sizeof(DATA), 0) < 0){
perror("send failed");
close(sock);
return -1;
}
printf("sent %s\n", DATA);
close(sock);
return -1;
}
Клиент должен при включении сообщать о себе, после чего устанавливается связь. Вот мо задача. IP адрес сервера неизвестен известен только порт. На сервере стоит ограниченное количество подключений и не факт что клиент возьмет и подключится. А вот серверу необходимо знать сколько у него есть клиентов которые могут к нему подключиться, тем более и клиент и сервер будут стоять на каждой машине. Но формально роль сервера будет выполнять только один пк. И ему нужно знать о всех клиентах, для этого нужно что бы клиент при включении сообщал серверу что он есть. И если будет нужно связь будет установлена либо с одной стороны либо с другой.
Ответы (2 шт):
Мне нужно что бы клиент отправлял широковещательный запрос для уведомления сервера о том что он есть.
То, что Вы описали, очень похоже на первую фазу протокола DHCP. Не вдаваясь в детали, это можно описать так:
- Клиент: "Есть в сети сервера?" (Широковещательный)
- Сервер: "Да, я тут есть!". (По IP отправителя пункта 1)
- Клиент: "А можно с тобой установить соединение?" (По IP из пункта 2)
- Сервер: "Да, выделяю тебе порт № на время N секунд)"
- Клиент: "Соединяюсь по IP сервера и порту, который мне выделен"
Все так, механизм похож, только приложение не выдает IP адреса да и работает на другом уровне модели OSI. Просто сервер не знает о том сколько у него,а 1 шаг DHCP это заявление клиента что он есть, у меня же наоборот. В общем случае без деталей мне нужно реализовать широковещательный SOCKET сервер и клиент используя СИ.