Здравствуйте, вот решил разобраться с сокетами.
Написал сервер (server.c):
#include
#include
#include
#include
#include
#include
#include
#define MAX_BUF_LEN 1024
#define MAX_LEN_NAME 124
int main (int argc, char * argv [])
{
int sock, client_sock, count;
char * buf, * hostname;
struct sockaddr_in addr;
struct hostent * host;
buf = (char *) malloc (MAX_BUF_LEN);
if (buf == NULL)
{
fprintf (stderr, «Problem with malloc ()\n»);
return -1;
}
sock = socket (PF_INET, SOCK_STREAM, 0);
if (sock == -1)
{
fprintf (stderr, «Problem with socket ()\n»);
return -1;
}
addr.sin_family = AF_INET;
//addr.sin_addr = * (struct in_addr*) host -> h_addr_list [0];
addr.sin_port = htons (6666);
hostname = (char *) malloc (MAX_LEN_NAME);
if (hostname == NULL)
{
fprintf (stderr, «Problem with malloc\n»);
return -1;
}
gethostname (hostname, MAX_LEN_NAME);
host = gethostbyname (hostname);
if (host == NULL)
{
fprintf (stderr, «Problem with gethostbyname()\n»);
return -1;
}
addr.sin_addr = * (struct in_addr *) host -> h_addr_list [0];
if (bind (sock, (struct sockaddr *) &addr, sizeof (addr)) == -1)
{
fprintf (stderr, «Problem with bind\n»);
return -1;
}
if (listen (sock, 10) == -1)
{
fprintf (stderr, «listen () error\n»);
return -1;
}
while ( 1 ) {
client_sock = accept (sock, NULL, NULL);
if (client_sock == -1)
{
fprintf (stderr, «Problem with accept\n»);
return -1;
}
if ((count = read (client_sock, buf, MAX_BUF_LEN-1)) == -1)
{
fprintf (stderr, «Problem with read()\n»);
return -1;
}
buf [count] = '\0\′;
printf («%s\n», buf);
close (client_sock);
if (!strcmp (buf, «exit»)) break;
}
free (buf);
close (sock);
return 0;
}
Сервер сидит на 127.0.0.1
Клиент (client.c):
#include
#include
#include
#include
#include
#define MAX_BUF_LEN 1024
int main (int argc, char * argv [])
{
int sock; char * buf;
struct sockaddr_in addr;
struct hostent * host;
if (argc < 2)
{
fprintf (stderr, «Too few arguments\n»);
return -1;
}
sock = socket (PF_INET, AF_INET, 0);
if (sock == -1)
{
fprintf (stderr, «Problem with socket()\n»);
return -1;
}
addr.sin_family = AF_INET;
host = gethostbyname (argv [1]);
if (host == NULL)
{
fprintf (stderr, «Problem with host\n»);
return -1;
}
addr.sin_addr = * (struct in_addr *) host -> h_addr_list [0];
addr.sin_port = htons (6666);
if (connect (sock, (struct sockaddr *) &addr, sizeof (addr)) == -1)
{
fprintf (stderr, «problem with connect\n»);
return -1;
}
buf = (char *) malloc (MAX_BUF_LEN);
if (buf == NULL)
{
fprintf (stderr, «Problem with malloc\n»);
return -1;
}
fgets (buf, MAX_BUF_LEN, stdin);
if (write (sock, buf, MAX_BUF_LEN) == -1)
{
fprintf (stderr, «Problem with write()\n»);
return -1;
}
close (sock);
return 0;
}
Клиент коннектится к серверу через ip адрес.
проблема в том что клиент не коннектиться, сообщения вводятся
но до сервера не доходят, либо уходят куда не надо.
$ telnet localhost 6666 Вот так все отлично
А вот:
$ telnet ip 6666 не работает
Для решения проблемы:
-- пробовал сделать чтоб сервер сидел на моем ip. Но почему то всегда
выводится ошибка с bind. адресс не присваивается. ???
-- запускал клиента в виде:
$ ./client ip_addr
В качестве ip_addr указывал свой ip, пробовал указывать и localhost.
-- файервола нет.
Заранее, спасиб.
Последние комментарии
- OlegL, 17 декабря в 15:00 → Перекличка 21
- REDkiy, 8 июня 2023 года в 9:09 → Как «замокать» файл для юниттеста в Python? 2
- fhunter, 29 ноября 2022 года в 2:09 → Проблема с NO_PUBKEY: как получить GPG-ключ и добавить его в базу apt? 6
- Иванн, 9 апреля 2022 года в 8:31 → Ассоциация РАСПО провела первое учредительное собрание 1
- Kiri11.ADV1, 7 марта 2021 года в 12:01 → Логи catalina.out в TomCat 9 в формате JSON 1
bind надо делать на IN_ADDR_ANY. Проверь точное название в man.
addr.sin_addr.s_addr = htonl (INADDR_ANY);
Если вот так, тогда telnetом можо коннектиться к ip на порт 6666.
Непонятно вот что почему первоначальная версия не верна?
hostname = (char *) malloc (MAX_LEN_NAME);
if (hostname == NULL)
{
fprintf (stderr, «Problem with malloc\n»);
return -1;
}
gethostname (hostname, MAX_LEN_NAME);
host = gethostbyname (hostname);
if (host == NULL)
{
fprintf (stderr, «Problem with gethostbyname()\n»);
return -1;
}
addr.sin_addr = * (struct in_addr *) host -> h_addr_list [0];
Посмотрел обозначение макроса INADDR_ANY
это локальный адрес. 127.0.0.1
Ну почему моей версией не выходит ???
Пробовал в клиенте поменять на это:
addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
Все равно не коннектится.
INADDR_ANY — это адрес 0.0.0.0 и ядро получив егов системном вызове знает что надо прибиндится на все сетевые интерфейсы. Если ты указываешь конкретный адрес, то биндится только на него.
Теперь ясно. Спасиб.
0×00000000
точно. посмотрел.
Я спутал с INADDR_LOOPBACK, вот у него как раз 0×7f000001, локальный.
Я переделал сервер, теперь он биндится на мой ip, работает успешно, telnet передает ему сообщение. А вот Клиент не работает, почему не ясно…
т.е клиент скорей всего коннектится к моей тачке, только сообщения не приходят…
Для решения проблемы :
Пробовал не просто писать в сокет, затем на сервере читать его,
а сделал через send и recv. Не помогает.
fgets проверь на ошибку.
проверил, без изменений.
По идеи там не верно, прочитай про fdopen.
fgets (buf, MAX_BUF_LEN, stdin);
Что в ней не так? Если ты про последний символ в buf, ясно что там enter. Переделал под scanf.
0 результат.
Я ж не в сокет ввожу, а в buf. И затем его отсылаю через send.
Аль я тебя не допонял.
во ошибка в клиенте: sock = socket (PF_INET, AF_INET, 0);
надо sock = socket (PF_INET, SOCK_STREAM, 0);
Да нет, все в ней верно, у меня были не верные представление о типе stdin.