@Jeboxa-developer
Начинающий разработчик

Как сделать, чтобы могли подключится пользователя?

Код сервера:
server.c

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include

#include

#define PORT "3496" // the port users will be connecting to

#define BACKLOG 10 // how many pending connections queue will hold

void sigchld_handler(int s)
{
while(waitpid(-1, NULL, WNOHANG) > 0);
}

// get sockaddr, IPv4 or IPv6:
void *get_in_addr(struct sockaddr *sa)
{
if (sa->sa_family == AF_INET) {
return &(((struct sockaddr_in*)sa)->sin_addr);
}

return &(((struct sockaddr_in6*)sa)->sin6_addr);
}

int main(void)
{
int sockfd, // listen
new_fd; // new connection

struct addrinfo hints, //socket
*servinfo, // будет указывать на связанный список структур addrinfo, , каждый из которых будет содержать struct sockaddr и многое другое, что мы будем использовать в дальнейшем.
*p; // temp var для перебора все структур и поиска первой подходящей

struct sockaddr_storage their_addr; // connector's address information

socklen_t sin_size;
struct sigaction sa;
int yes=1;
char s[INET6_ADDRSTRLEN];
int rv;

memset(&hints, 0, sizeof hints); // заполняем нулями адрес
hints.ai_family = AF_UNSPEC; // использовать любой IP (4/6)
hints.ai_socktype = SOCK_STREAM; // TCP
hints.ai_flags = AI_PASSIVE; // use my IP




if ((rv = getaddrinfo(NULL, PORT, &hints, &servinfo)) != 0) { // return 0 if все в порядке. Также она записывает связанынй список и инициализауерт ai_next
fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
return 1;
}

for(p = servinfo; p != NULL; p = p->ai_next) {

if ((sockfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1) {
perror("server: socket");
continue;
}
std::cout << sockfd << std::endl;
if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1) {
perror("setsockopt");
exit(1);
}

if (bind(sockfd, p->ai_addr, p->ai_addrlen) == -1) {
close(sockfd);
perror("server: bind");
continue;
}

break;
}

if (p == NULL) {
fprintf(stderr, "server: failed to bind\n");
return 2;
}

freeaddrinfo(servinfo); // all done with this structure

if (listen(sockfd, BACKLOG) == -1) {
perror("listen");
exit(1);
}

sa.sa_handler = sigchld_handler; // reap all dead processes
sigemptyset(&sa.sa_mask);
sa.sa_flags = SA_RESTART;
if (sigaction(SIGCHLD, &sa, NULL) == -1) {
perror("sigaction");
exit(1);
}

printf("server: waiting for connections...\n");


while(1) { // main accept() loop
sin_size = sizeof their_addr;
new_fd = accept(sockfd, (struct sockaddr *)&their_addr, &sin_size);
if (new_fd == -1) {
perror("accept");
continue;
}

inet_ntop(their_addr.ss_family,
get_in_addr((struct sockaddr *)&their_addr),
s, sizeof s);
printf("server: got connection from %s\n", s);

if (!fork()) { // this is the child process
close(sockfd); // child doesn't need the listener
if (send(new_fd, "sssssss", 3, 0) == -1)
perror("send");
close(new_fd);
exit(0);
}
close(new_fd); // parent doesn't need this
}

return 0;
}


Код клиента:
client.c

#include
#include
#include
#include
#include
#include
#include
#include
#include

#include

#include

#define PORT "3496" // the port client will be connecting to

#define MAXDATASIZE 100 // max number of bytes we can get at once

// get sockaddr, IPv4 or IPv6:
void *get_in_addr(struct sockaddr *sa)
{
if (sa->sa_family == AF_INET) {
return &(((struct sockaddr_in*)sa)->sin_addr);
}

return &(((struct sockaddr_in6*)sa)->sin6_addr);
}

int main(int argc, char *argv[])
{
int sockfd, numbytes;
char buf[MAXDATASIZE];
struct addrinfo hints, *servinfo, *p;
int rv;
char s[INET6_ADDRSTRLEN];

if (argc != 2) {
fprintf(stderr,"usage: client hostname\n");
exit(1);
}

memset(&hints, 0, sizeof hints);
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;


if ((rv = getaddrinfo(argv[1], PORT, &hints, &servinfo)) != 0) {
fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
return 1;
}

// loop through all the results and connect to the first we can
for(p = servinfo; p != NULL; p = p->ai_next) {
if ((sockfd = socket(p->ai_family, p->ai_socktype,
p->ai_protocol)) == -1) {
perror("client: socket");
continue;
}

if (connect(sockfd, p->ai_addr, p->ai_addrlen) == -1) {
close(sockfd);
perror("client: connect");
continue;
}

break;
}

if (p == NULL) {
fprintf(stderr, "client: failed to connect\n");
return 2;
}

inet_ntop(p->ai_family, get_in_addr((struct sockaddr *)p->ai_addr),
s, sizeof s);
printf("client: connecting to %s\n", s);

freeaddrinfo(servinfo); // all done with this structure

if ((numbytes = recv(sockfd, buf, MAXDATASIZE-1, 0)) == -1) {
perror("recv");
exit(1);
}

buf[numbytes] = '\0';

printf("client: received '%s'\n",buf);

close(sockfd);

return 0;
}


Если я запсукаю сервер, то к нему могут подключится пользователи зи этой же сети. Но как мне сделать, например, чтобы подключился мой друг?
Если я пишу ifconfig - вставляю inet в функцию getaddrinfo вместо NULL, все равно не работает.
  • Вопрос задан
  • 144 просмотра
Решения вопроса 1
@vitaly_il1
DevOps Consulting
Если я запсукаю сервер, то к нему могут подключится пользователи зи этой же сети.

Сеть внутренняя? У сервера должен быть внешний адрес, или проброс портов на внешний адрес, чтобы могли подключаться снаружи.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы