Сетевое программирование, сокеты (help!)
Модератор: Модераторы разделов
-
- Сообщения: 105
- ОС: Linux Mint 11 Katya
Re: Сетевое программирование, сокеты
получилась такая концепция: сервер работает постоянно(эхо-сервер). клиент запускается, отправляет сообщение, принимает с сервера, выводит на экран и заканчивает работу. нужно сделать так чтоб можно было отправлять сообщения и принимать их как на сервере, так и на клиенте. и чтоб клиент сам не завершал работу. не могу додуматься как это сделать. Подскажите пожалуйста как это можно сделать.
-
- Сообщения: 1263
- ОС: Linux Debian
Re: Сетевое программирование, сокеты
rza писал(а): ↑09.12.2008 16:59получилась такая концепция: сервер работает постоянно(эхо-сервер). клиент запускается, отправляет сообщение, принимает с сервера, выводит на экран и заканчивает работу. нужно сделать так чтоб можно было отправлять сообщения и принимать их как на сервере, так и на клиенте. и чтоб клиент сам не завершал работу. не могу додуматься как это сделать. Подскажите пожалуйста как это можно сделать.
Не поняно, что именно надо. Какие сообщения, кто и от кого должен принимать? Что имеется ввиду под сервером и клиентом?
Что значит "чтоб клиент сам не завершал работу"? А что он должен делать?
skillergti писал(а): ↑05.12.2008 01:21Очевидно, Брюс Моли "Unix/Linux теория и практика программирования".
Нет, Кейт Хэвиленд, Дайна Грэй, Бен Салама. "Системное программирование в UNIX" Руководство программиста по разработке ПО
Есть на обложке ещё более мелкая заись "Универсальная среда программирования"
-
- Сообщения: 105
- ОС: Linux Mint 11 Katya
Re: Сетевое программирование, сокеты
клиент отправляет сообщение - эхо-сервер его возвращает - клиент закрывается. а на да чтоб
запустить клиент и сервер - передавать сообщения и выводить их и там и там.
сервер - программа которая создаёт сокет.
клиент - программа которая соединяется с этим сокетом.
надо сделать так чтоб когда была включена программа мне выводились бы все присланные сообщения и я бы мог в любой момент отправить свое.
запустить клиент и сервер - передавать сообщения и выводить их и там и там.
сервер - программа которая создаёт сокет.
клиент - программа которая соединяется с этим сокетом.
надо сделать так чтоб когда была включена программа мне выводились бы все присланные сообщения и я бы мог в любой момент отправить свое.
-
- Сообщения: 260
- ОС: Debian Etch, RHEL-5.4
Re: Сетевое программирование, сокеты
Посмотри в направлении функции select()
Послужной список: Slackware-3.x, RedHat-4.x,5.x,6.x,7.x, FedoraCore-3, Debian Etch/Lenny
Осваиваю: RHEL-5.4
Осваиваю: RHEL-5.4
-
- Сообщения: 105
- ОС: Linux Mint 11 Katya
Re: Сетевое программирование, сокеты
посмотрел с select()
сложновато. ничего не понял. а что если запустить 2 функции в 2 потоках? сложно это реализовать? чтоб 1ф-ция выводила а 2 вводила в сокает. ????
сложновато. ничего не понял. а что если запустить 2 функции в 2 потоках? сложно это реализовать? чтоб 1ф-ция выводила а 2 вводила в сокает. ????
-
- Сообщения: 1263
- ОС: Linux Debian
Re: Сетевое программирование, сокеты
Клиент закрывается, когда в нём выполняется exit или return или просто достигается конец функции.
Т.е. надо сделать что-то вроде IRC-сервера? Т.е. клиент тоже должен быть сервером, чтобы принимать сообзения от основного сервера?
Но тогда и на сервере надо вести список всех подключённых к нему клиентов и при получении сообщения от любого посылать это сообщение всем остальным.
Что касается функции select()... я ей пока ещё ни разу не пользовался. Как я понимаю, она позволяет в одном потоке выполнять чтение из нескольких "каналов" (файлов) -- в зависимости от того, где раньше появится информация.
В данном варианте, думаю, надо организовывать чтение как из сокета, который связан с сервером, так и из файла клавиатурного ввода. При появлении данных с клавиатуры -- введённую строку передавать на сервер, а при появлении данных от севера -- полученную информацию выводить на терминал.
-
- Сообщения: 105
- ОС: Linux Mint 11 Katya
Re: Сетевое программирование, сокеты
а как проверять появление данных с клавиатуры? и как проверять появления данных с сервера?
>>>>
Т.е. надо сделать что-то вроде IRC-сервера? Т.е. клиент тоже должен быть сервером, чтобы принимать сообзения от основного сервера?
>>>>
да! если можете напишите функции которіе применять или маленький кусочек исходника (фрагмент).
>>>>
Т.е. надо сделать что-то вроде IRC-сервера? Т.е. клиент тоже должен быть сервером, чтобы принимать сообзения от основного сервера?
>>>>
да! если можете напишите функции которіе применять или маленький кусочек исходника (фрагмент).
-
- Сообщения: 1263
- ОС: Linux Debian
Re: Сетевое программирование, сокеты
К сожалению пока этого сделать не могу. Просто потому, что такую задачу решать ещё не приходилось.
Но могу предложить почитать фрагмент из упомянутой мной книги про функцию select
Там есть пример программы, правда, я её не проверял и поэтому в ней возможны ошибки (я делал страницы с помощью ФайнРидера, а он может понимать текст не так, как человек)
Что касается чтение данных с клавиатуры, то его можно выполнять по read(0,... . Т.к. дексриптор 0 связан с stdin (1 -- c stdout и 2 -- c stderr).
Ну а дальше остаётся только разобраться как работает та программа
-
- Сообщения: 260
- ОС: Debian Etch, RHEL-5.4
Re: Сетевое программирование, сокеты
Приношу свои извинения, не посмотрел внимательно куда ссылка идёт. В качестве реабилитации привожу кусок своего древнего кода где использовалась функция select():
Код:
int main(void)
{
int i, len, strob;
int SelectResult;
fd_set fdset, fdred;
for(i=0;i<MAX_USER;i++)
{
ChannelCount[i] = 0;
csock[i] = 0;
}
get_socket();
for(;; )
{
FD_ZERO(&fdset);
FD_SET(sock, &fdset);
FD_SET(ssock,&fdset);
FD_ZERO(&fdred);
#ifdef NO_INMOS
FD_SET(tsock,&fdset);
strob = tsock;
#else
strob = ssock;
#endif
for( i=0; i<MAX_USER; i++ )
if( csock[i] )
{
FD_SET(csock[i], &fdset);
if( strob < csock[i] )
{
strob = csock[i];
}
}
SelectResult = select(strob+1, &fdset, NULL, NULL, NULL);
if( SelectResult >0 )
{
/* Ask from new Client for connection */
if( FD_ISSET(sock, &fdset) || FD_ISSET(ssock,&fdset) )
{
if( FD_ISSET(sock, &fdset) )
bsock = sock;
else
bsock = ssock;
nsock = accept(bsock, (struct sockaddr *)0, (int *)0);
if (nsock == -1) {
#ifdef BSD
if( errno == EINTR ) {
signal(SIGCHLD, sigchld);
continue; }
#endif
; }
else
{ len = read_s(nsock, sv.string, sizeof(sv.string));
if( len > 0 )
{
client_registration(nsock, sv.string);
}
if(nsock) nsock = 0;
}
} /* if */
else
{
for( i=0; i<MAX_USER; i++ )
if(csock[i])
if( FD_ISSET(csock[i], &fdset) )
/* || FD_ISSET(csock[i], &fdred) ) */
{
s_client_event(i);
}
} /* else */
} /* if( select() ) */
} /* for(;; ) */
} /* main() */
Сперва создается список сокетов функциями FD_ZERO(), FD_SET(), FD_ISSET(), а потом select() проверяет, пришло ли что-нибудь по ним. Запросы обрабатывает в порядке поступления. Подробности смотри в описаниях функций.
Послужной список: Slackware-3.x, RedHat-4.x,5.x,6.x,7.x, FedoraCore-3, Debian Etch/Lenny
Осваиваю: RHEL-5.4
Осваиваю: RHEL-5.4
-
- Сообщения: 105
- ОС: Linux Mint 11 Katya
Re: Сетевое программирование, сокеты
объясните как правильно работать с потоками? какие особенности? какие функции применять? если может кто то с этим сталкивался может что подскажет. опять же может кусочек исходника.
-
- Сообщения: 105
- ОС: Linux Mint 11 Katya
Re: Сетевое программирование, сокеты
и ещё . сокет создается в main(). как сделать чтоб его можна было использовать в других функциях тоесть сделать как бы глобальной переменной?? какого она типа - переменная имя сокета??
-
- Сообщения: 135
- ОС: FreeBSD 8.0-RELEASE amd64
Re: Сетевое программирование, сокеты
rza писал(а): ↑09.12.2008 16:59получилась такая концепция: сервер работает постоянно(эхо-сервер). клиент запускается, отправляет сообщение, принимает с сервера, выводит на экран и заканчивает работу. нужно сделать так чтоб можно было отправлять сообщения и принимать их как на сервере, так и на клиенте. и чтоб клиент сам не завершал работу. не могу додуматься как это сделать. Подскажите пожалуйста как это можно сделать.
Читать Стивенса! У него эта задача во все щели насилуется, вернее, на ее примере показываются различные подходы.
Ничего не путаете? На сервере создается прослушиваемый сокет, на стороне клиента - присоединенный.
Насчет посикс-потоков можно начать вот с этого: https://computing.llnl.gov/tutorials/pthreads/
Дескриптор сокета - это просто целое число, притом, int. Таким образом, достаточно просто передать его по значению в нужную Вам функцию.
-
- Сообщения: 105
- ОС: Linux Mint 11 Katya
Re: Сетевое программирование, сокеты
а вот ещё вопрос. операторы перегружены << >>. но я могу их использовать только в main() для других функций которые я создал он не перегружен. в чем дело? помогите. кстати не найду ссылку на скачку Стивенса. или только покупать? а покупать дороговато.
-
- Сообщения: 135
- ОС: FreeBSD 8.0-RELEASE amd64
Re: Сетевое программирование, сокеты
Лучше конечно купить, ибо бумага, ИМХО, удобнее. Но если нет, то вроде гуглится нормально

http://www.google.com/search?hl=en&cli...amp;btnG=Search
Во первых, для чего Вы используете <<, >>? Во вторых, не надо их использовать, дабы не иметь проблем с буферизацией stdstream.
-
- Сообщения: 105
- ОС: Linux Mint 11 Katya
Re: Сетевое программирование, сокеты
для простоты работы с скетами было сделано вот что. перегрузка << >>. string>>socket в строковую переменную запись. вот так. или не стоит єтого делать?
спасибо большое за Стивенса! книга очень хорошая.
спасибо большое за Стивенса! книга очень хорошая.
-
- Сообщения: 135
- ОС: FreeBSD 8.0-RELEASE amd64
Re: Сетевое программирование, сокеты
Это тот случай, когда применение С++ совершенно бесполезно и неоправдано. А вообще, наиболее интересно это было бы сделать, используя select и не блокируемые операции.
-
- Сообщения: 105
- ОС: Linux Mint 11 Katya
Re: Сетевое программирование, сокеты
подскажите как сделать так чтоб перегрузка работала во всех функциях, а не только в main()
-
- Сообщения: 105
- ОС: Linux Mint 11 Katya
Re: Сетевое программирование, сокеты
–lpthread не подключается в параметрах компилера. что это может быть?
-
- Сообщения: 135
- ОС: FreeBSD 8.0-RELEASE amd64
-
- Сообщения: 1263
- ОС: Linux Debian
Re: Сетевое программирование, сокеты
А что именно не подключается? –lpthread или -lpthread ?
Сейчас вспоминаю, что у меня как-то была именно эта проблема -- брал код из html текста, а там вместо знака "HYPHEN-MINUS" ('-') оказался знак "EN DASH" ('–')
Причину искал довольно долго.
-
- Сообщения: 105
- ОС: Linux Mint 11 Katya
Re: Сетевое программирование, сокеты
http://citforum.ru/programming/unix/threads/ вот ссылка . копировал прямо со странички. может и вправду
<<вместо знака "HYPHEN-MINUS" ('-') оказался знак "EN DASH" ('–')<< . может кто то попробует скомпилить эту прогу?? всем спасибо.
<<вместо знака "HYPHEN-MINUS" ('-') оказался знак "EN DASH" ('–')<< . может кто то попробует скомпилить эту прогу?? всем спасибо.
-
- Сообщения: 1263
- ОС: Linux Debian
Re: Сетевое программирование, сокеты
rza писал(а): ↑16.12.2008 17:20http://citforum.ru/programming/unix/threads/ вот ссылка . копировал прямо со странички. может и вправду
<<вместо знака "HYPHEN-MINUS" ('-') оказался знак "EN DASH" ('–')<< . может кто то попробует скомпилить эту прогу?? всем спасибо.
Похоже, это именно тот самый пример, на который я не так давно наталкивался
Вот изображение строки, вставленной в geany:
Как видно, чёрточка перед словом lpthread длинее, чем аналогичная перед другими словами. А значит там стоит не обычный знак '-', а другой.
Соответственно, компилятор пытается интерпретировать всё слово "–lpthread" и не понимает его
Замените его на обычный минус и всё должно пройти.
У вас нет необходимых прав для просмотра вложений в этом сообщении.
-
- Сообщения: 105
- ОС: Linux Mint 11 Katya
-
- Сообщения: 105
- ОС: Linux Mint 11 Katya
Re: Сетевое программирование, сокеты
вот мне нужно сделать клиент который параллельно принимает и отправляет сообщения. я запустил две функции в 2 потоках. функция ввода - запрос ввода строки а потом send(),в бесконечном цикле; функция вывода recv() и тоже в бесконечном цикле. но программа не запускается. компилируется но не запускается. скорее я не правильно что то додумал. помогите пожалуйста.
-
- Сообщения: 135
- ОС: FreeBSD 8.0-RELEASE amd64
-
- Сообщения: 135
- ОС: FreeBSD 8.0-RELEASE amd64
-
- Сообщения: 105
- ОС: Linux Mint 11 Katya
Re: Сетевое программирование, сокеты
Код:
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <pthread.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
char message[30];
char buf[sizeof(message)];
int sock;
void * f_zap()
{
for (;;)
{
printf("%s","vvod","/n");
scanf("%s",message);
send(sock, message, sizeof(message), 0);
}
}
void * f_rec()
{
for(;;)
{
printf("%s",">>");
recv(sock, buf, sizeof(message), 0);
printf(buf);
}
}
int main()
{
int id1, id2, result;
pthread_t thread1, thread2;
struct sockaddr_in addr;
sock = socket(AF_INET, SOCK_STREAM, 0);
if(sock < 0)
{
perror("socket");
exit(1);
}
addr.sin_family = AF_INET;
addr.sin_port = htons(3425); // ╨╕╨╗╨╕ ╨╗╤Д╨▒╨╛╨╣ ╨┤╤З╤в╨│╨╛╨╣ ╨┐╨╛╤З╤й...
addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
if(connect(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0)
{
perror("connect");
exit(2);
}
id1 = 1;
result = pthread_create(&thread1, NULL, f_zap, &id1);
id2 = 2;
result = pthread_create(&thread2, NULL, f_rec, &id2);
close(sock);
return 0;
}
вот это клиент. а сервер работает как эхо с ним проблем пока нет.
-
- Сообщения: 135
- ОС: FreeBSD 8.0-RELEASE amd64
Re: Сетевое программирование, сокеты
Все не так. См. Стивенс "26.3 Использование потоков в функции str_cli".
Вообще, в глаза бросается следующее:
Код: Выделить всё
printf("%s","vvod","/n");
Код: Выделить всё
scanf("%s",message);
Код: Выделить всё
gets(message, sizeof(message), stdin)
Код: Выделить всё
printf(buf);
Код: Выделить всё
puts(buf);
Код: Выделить всё
void * f_zap()
void * f_rec()
Код: Выделить всё
id1 = 1;
id2 = 2;
Код: Выделить всё
close(sock);
Код: Выделить всё
return 0;
Вопросы?
-
- Сообщения: 105
- ОС: Linux Mint 11 Katya
Re: Сетевое программирование, сокеты
>>Если мы так сразу выйдем, то заодно прибьем запущенные потоки, в которых выполняется полезная работа. Не правда ли, странно?
потоки убиваются. так а как это исправить?
>>close(sock);
а где это писать?
а правильно ли в бесконечном цикле запрашивать ввод??
потоки убиваются. так а как это исправить?
>>close(sock);
а где это писать?
а правильно ли в бесконечном цикле запрашивать ввод??
-
- Сообщения: 135
- ОС: FreeBSD 8.0-RELEASE amd64
Re: Сетевое программирование, сокеты
После запуска потоков нужно дождаться их завершения:
Код: Выделить всё
pthread_join(&thread1, NULL);
pthread_join(&thread2, NULL)
А вот когда потоки завершены можно и закрыть сокет, хотя, при выходе все дескрипторы закрываются автоматически.
Это как раз совершенно нормально. Правда, Вам, как я понял, нужно читать строку, а не произвольные данные, поэтому recv здесь так влоб применять нельзя. Ну подумайте, Вы этой функцией читаете какие-то данные, количество которых не превышает заданную длину. Но это не дает никакой гарантии, что в этот буфер будет прочитана строка - в результате Вы почти наверняка выведите мусор, который находится за принимаемым буфером. В общем, посмотрите функцию readline у Стивенса