Кроссплатформенный клиент-сервер

Тема в разделе "WASM.UNIX", создана пользователем Max, 3 июн 2008.

  1. Max

    Max Member

    Публикаций:
    0
    Регистрация:
    22 май 2003
    Сообщения:
    192
    Требуется темплейт кроссплатформенного (win32 + freeBSD) клиент-сервера на Си.
    Никто не видел?
    Или может ссылок кто подкинет на сайты по программингу под Unix-системы на Си.
     
  2. _basmp_

    _basmp_ New Member

    Публикаций:
    0
    Регистрация:
    10 июл 2005
    Сообщения:
    2.939
    Max
    непонял. что за клиент сервер? в чем его кроссплатформенность? поподробнее нельзя-ли?
     
  3. Max

    Max Member

    Публикаций:
    0
    Регистрация:
    22 май 2003
    Сообщения:
    192
    Экзампел нужен клиента + многопоточного сервера (socket, accept, connect, тра-ля-ля), и чтоб компилился как под вин, так и под юникс.
    Ну там прокси какой нибудь, или чат, или может пример от какой-нибудь книжки.
    Главное - попроще, я конечно могу mysql качнуть, но там черт ногу сломит.
    Надо чтоб взять за основу и туда накрутить свою функциональность...
     
  4. _basmp_

    _basmp_ New Member

    Публикаций:
    0
    Регистрация:
    10 июл 2005
    Сообщения:
    2.939
    Max
    Опять не понял. Ну апач компилится под то и под то. Ну мозилла компилится. Вам зачем надо? Лаба?
     
  5. censored

    censored New Member

    Публикаций:
    0
    Регистрация:
    5 июл 2005
    Сообщения:
    1.615
    Адрес:
    деревня "Анонимные Прокси"
    server: apache
    client: lynx
     
  6. Max

    Max Member

    Публикаций:
    0
    Регистрация:
    22 май 2003
    Сообщения:
    192
    Идея была взять какой нибудь _простой_ готовый код, типа как в экзамплах например Рихтера, когда он байтики гоняет туда-сюда, выкинуть лишнее и вставить свой протокол.
    И чтоб экзампел кроссплатформенный был.

    Так как боюсь, что с апачем или с мозиллой я буду дольше разбираться, чем свой с нуля напишу.

    Ладно, спасибо, посмотрю апач...

    Нее, там навороченная хрень, типа СУБД, просто хотелось взять быстрый старт :)
     
  7. _basmp_

    _basmp_ New Member

    Публикаций:
    0
    Регистрация:
    10 июл 2005
    Сообщения:
    2.939
    Max
    тут вам не с 0 стартовать надо. Поищите на gnu или sf готовую либу-оболочку. Да и тут на форуме недавно вопрос был о переносимых интерфейсах СУБД.
     
  8. _basmp_

    _basmp_ New Member

    Публикаций:
    0
    Регистрация:
    10 июл 2005
    Сообщения:
    2.939
  9. n0name

    n0name New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2004
    Сообщения:
    4.336
    Адрес:
    Russia
    клиент:
    Код (Text):
    1. #include <sys/socket.h>
    2. #include <sys/types.h>
    3. #include <sys/time.h>
    4. #include <netinet/in.h>
    5. #include <stdio.h>
    6. #include <stdlib.h>
    7. #include <limits.h>
    8. #include <signal.h>
    9. #include <netdb.h>
    10.  
    11. int clientSocket = -1;
    12.  
    13. void usage(char *pname)
    14. {
    15.     printf("Usage: %s -p port -s server [-h]\n\tserver by default is '127.0.0.1'\n", pname);
    16. }
    17.  
    18. void fsignal(int sig)
    19. {
    20.     switch(sig)
    21.     {
    22.     case SIGTERM:
    23.     case SIGINT:
    24.     case SIGQUIT:
    25.         close(clientSocket);
    26.         exit(0);
    27.         break;
    28.     }
    29. }
    30.  
    31. int main(int argc, char *argv[])
    32. {
    33.     unsigned long port = ULONG_MAX, ip = 0;
    34.     int i, sinLen, ping;
    35.     char *p, *serv = 0, sbuf[2048];
    36.     struct sockaddr_in sockAddr;
    37.     struct timeval src, buf;
    38.     struct hostent *he;
    39.     int avgc, total;
    40.    
    41.     if (argc == 1 || argc > 4) {
    42.     printf("Incorrect count of arguments.\n");
    43.     return 0;
    44.     }
    45.     for (i = 1; i < argc; i++) {
    46.         if (argv[i][0] != '-') {
    47.         printf("All arguments have to start with '-'.\n");
    48.         return 0;
    49.     }
    50.     switch (argv[i][1])
    51.     {
    52.         case 'h':
    53.         usage(argv[0]);
    54.         break;
    55.         case 'p':
    56.         port = strtoul(&argv[i][2], &p, 0);
    57.         if (port == ULONG_MAX || *p != 0) {
    58.             printf("Incorrect port value. Its have to be number.\n");
    59.         }
    60.         break;
    61.         case 's':
    62.         serv = (char *)&argv[i][2];
    63.         break;
    64.         default:
    65.         printf("Unknown argument. Type -h for help.\n");
    66.         return 0;
    67.     }
    68.     }
    69.     // if there is just -h as argument
    70.     if (port == ULONG_MAX) {
    71.     printf("Unknown port.\n");
    72.     return 0;
    73.     }
    74.     if (!serv)
    75.         serv = "127.0.0.1";
    76.     printf("Used port: %d, used server: %s\n", port, serv);
    77.     for (i = 1; i < 32; i++)
    78.     signal(i, fsignal);
    79.     ip = inet_addr(serv);
    80.     if (ip = INADDR_NONE) {
    81.         he = (struct hostent *)gethostbyname((const char *)serv);
    82.     if (!he)
    83.         return 0;
    84.     ip = *((unsigned long *)(he->h_addr_list[0]));
    85.     }
    86.     clientSocket = socket(AF_INET, SOCK_STREAM, 0);
    87.     if (clientSocket == -1)
    88.     return 0;
    89.     sockAddr.sin_family = AF_INET;
    90.     sockAddr.sin_addr.s_addr = ip;
    91.     sockAddr.sin_port = htons((short)port);
    92.     argc = 0;
    93.     total = 0;
    94. //    printf("00000000/00000000");
    95.     if (connect(clientSocket, (struct sockaddr *)&sockAddr, sizeof(sockAddr)) == -1) {
    96.         close(clientSocket);
    97.     return 0;
    98.     }
    99.     while (1){
    100.     gettimeofday(&buf, 0);
    101.     i = recv(clientSocket, sbuf, 2048, 0);
    102.     if (!i || i == -1) {
    103.         close(clientSocket);
    104.         return 0;
    105.     }
    106.     gettimeofday(&src, 0);
    107.     ping = (src.tv_sec - buf.tv_sec) * 1000000 + (src.tv_usec - buf.tv_usec);
    108.     avgc++;
    109.     total += ping;
    110. //  printf("\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b%08d/%08d", total / avgc, ping);
    111. //  printf("%08d/%08d\n", total / avgc, ping);
    112.         printf("%08d / %08d\n", total / avgc, ping);
    113.     }
    114.     return 0;
    115. }
    севрер:
    Код (Text):
    1. #include <sys/socket.h>
    2. #include <sys/types.h>
    3. #include <sys/time.h>
    4. #include <netinet/in.h>
    5. #include <stdio.h>
    6. #include <stdlib.h>
    7. #include <limits.h>
    8. #include <signal.h>
    9.  
    10. int serverSocket = -1;
    11. int clientSocket = -1;
    12.  
    13. void usage(char *pname)
    14. {
    15.     printf("Usage: %s -p port [-h]\n", pname);
    16. }
    17.  
    18. void fsignal(int sig)
    19. {
    20.     switch(sig)
    21.     {
    22.     case SIGTERM:
    23.     case SIGINT:
    24.     case SIGQUIT:
    25.         close(clientSocket);
    26.         close(serverSocket);
    27.         exit(0);
    28.         break;
    29.     }
    30. }
    31.  
    32. int main(int argc, char *argv[])
    33. {
    34.     unsigned long port = ULONG_MAX;
    35.     int i, sinLen, delta;
    36.     char sbuf[2048];
    37.     char *p;
    38.     struct sockaddr_in sockAddr;
    39.     struct timeval buf, src;
    40.    
    41.     if (argc == 1 || argc > 3) {
    42.     printf("Incorrect count of arguments.\n");
    43.     return 0;
    44.     }
    45.     for (i = 1; i < argc; i++) {
    46.         if (argv[i][0] != '-') {
    47.         printf("All arguments have to begin with '-'.\n");
    48.         return 0;
    49.     }
    50.     switch (argv[i][1])
    51.     {
    52.         case 'h':
    53.         usage(argv[0]);
    54.         break;
    55.         case 'p':
    56.         port = strtoul(&argv[i][2], &p, 0);
    57.         if (port == ULONG_MAX || *p != 0) {
    58.             printf("");
    59.             return 0;
    60.         }
    61.         break;
    62.         default:
    63.         printf("Unknown option. type -h to show usage.\n");
    64.         return 0;
    65.     }
    66.     }
    67.     // if there is just -h as argument
    68.     if (port == ULONG_MAX) {
    69.     printf("Put port in arguments.\n");
    70.     return 0;
    71.     }
    72.     for (i = 1; i < 32; i++)
    73.     signal(i, fsignal);
    74.     serverSocket = socket(AF_INET, SOCK_STREAM, 0);
    75.     if (serverSocket == -1)
    76.     return 0;
    77.     sockAddr.sin_family = AF_INET;
    78.     sockAddr.sin_addr.s_addr = INADDR_ANY;
    79.     sockAddr.sin_port = htons((short)port);
    80.     if (bind(serverSocket, (struct sockaddr *)&sockAddr, sizeof(sockAddr)) == -1){
    81.     close(serverSocket);
    82.     return 0;
    83.     }
    84.     if (listen(serverSocket, 10) == -1){
    85.     close(serverSocket);
    86.     return 0;
    87.     }
    88.     sinLen = sizeof(sockAddr);
    89.     while ((clientSocket = accept(serverSocket, (struct sockaddr *)&sockAddr, &sinLen)) > 0){
    90.     i = fork();
    91.     if (i == -1)
    92.         printf("fork() error.\n");
    93.     if (!i) {
    94.             printf("Client with ip %08X connected.\n", sockAddr.sin_addr.s_addr);
    95.             do {
    96.         i = send(clientSocket, sbuf, 2048, 0);
    97.         if (!i || i == -1)
    98.             break;
    99.         } while (1);
    100.         close(clientSocket);
    101.         return 0;
    102.     }
    103.     printf("Process forked.\n");
    104.     }
    105.     return 0;
    106. }
    работает на линухе, солярке, винде.
     
  10. Max

    Max Member

    Публикаций:
    0
    Регистрация:
    22 май 2003
    Сообщения:
    192
  11. Max

    Max Member

    Публикаций:
    0
    Регистрация:
    22 май 2003
    Сообщения:
    192
    n0name
    А кто нибудь юзал Dev-C++?
    Я вот поставил, возникли траблы с компиляцией - даже вышеприведенный пример, требует инклудов, который нет после инсталляции (взять тот же <sys/socket.h>, котрого по дефолту нет, или тот-же <netinet/in.h>, который тянет за собой хренову тучу инклудов).
    Пробовал переливать инклуды непосредственно с ФриБСД, но они, во-первых, не соответствуют по сруктуре каталогов, а во-вторых, заметно отличаются в размере, что приводит к тому, что компилятор начинает матюкаться.

    Гуглил всю ночь - тема известная, под винду ответов нет, кто знает, поделитесь опытом - как это дело собрать под Dev-C++??
     
  12. iZzz32

    iZzz32 Sergey Sfeli

    Публикаций:
    0
    Регистрация:
    3 сен 2006
    Сообщения:
    355
    Max, этот пример в винде неработоспособен (как минимум, нет WSAStartup и есть fork), поэтому он соберётся и будет работать разве что под cygwin-ом. Лучше погугли что-нибудь наподобие «select based server».
     
  13. Xerx

    Xerx Алексей

    Публикаций:
    0
    Регистрация:
    17 фев 2005
    Сообщения:
    528
    Адрес:
    Russia
    Max
    Я почти всегда при использовании C++ пишу в DevC++.

    Ну так! Приведенные заголовочники - из *nix, а DevC++ работает под Win. Прямого портирования не получится. Тут нужно смотреть какие структуры/константы/типы используются и какие функции вызываются, искать их в имеющихся либах и те же линковать. Ну или искать порт данных либ под Win.

    Если будут проблемы - могу посмотреть код сегодня-завтра. Хотя, конечно же, 100% порт невозможен, слишком специфичное приложение пишется ( одна строка "if((parpid=fork())<0)" чего стоит ).
     
  14. device

    device Reflection

    Публикаций:
    0
    Регистрация:
    26 апр 2007
    Сообщения:
    1.198
    Адрес:
    RF
    Ну, в винде есть cyGWin - там форкнуть можно.

    Пайпы - не работают, хотя компиляццо.
     
  15. r90

    r90 New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2005
    Сообщения:
    898
    Можно. Но если в *nix fork -- это copy-on-write, то в cygwin -- это копирование всего и сразу. То есть такой форк вешать реакцией на удачный accept не стоит.
     
  16. device

    device Reflection

    Публикаций:
    0
    Регистрация:
    26 апр 2007
    Сообщения:
    1.198
    Адрес:
    RF
    r90
    Язык тогда неудачно выбран.
    Стоит задача:
    Создать клиент и сервак кроссплатформенные.

    Java, Ada? Почему нет? Задачу решаем средствами, которые для этого предназначены. Если мне закажут драйвер, я же не буду писать его на ассемблере! Так и тут.
     
  17. Xerx

    Xerx Алексей

    Публикаций:
    0
    Регистрация:
    17 фев 2005
    Сообщения:
    528
    Адрес:
    Russia
    а зачем вообще использовать такую специфику? просто написать клиент-сервер в unix-like стиле: многопоточно с блокирующими сокетами. переносимость будет порядка 80% - править оболочку и некоторые моменты сетевой части.
     
  18. r90

    r90 New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2005
    Сообщения:
    898
    device
    C -- вполне себе кроссплатформенный язык. Но если представлять себе проблемы не-*nix систем. С учётом специфики windows к созданию процессов надо подходить с опаской. Либо использовать левые библиотеки, либо #ifdef'ы. Либо не использовать процессы вообще.
     
  19. Max

    Max Member

    Публикаций:
    0
    Регистрация:
    22 май 2003
    Сообщения:
    192
    Народ, вы меня пугаете :-/
    Неужто такую банальную вещь нельзя реализовать кроссплатформенно?
    Как тогда вообще можно говорить о кроссе?
    Тем более, что n0name написал, что "работает на линухе, солярке, винде".
    Значит как-то можно?

    з.ы. C/C++ - требование заказчика
     
  20. P_F

    P_F New Member

    Публикаций:
    0
    Регистрация:
    27 мар 2006
    Сообщения:
    116
    Адрес:
    Russia
    в винде оно может и работает, только из под эмуля какого, как собственно было сказано.

    варианты:
    1. заюзать какую нибуть кросплатформенную либу (напримет QT)
    2. написать с нуля :), если решишь смотри в сторону winapi функций стандарта posix + #ifdef позволяющие подключить взависимости от платформы сборки нужный хидер.
    что собственно тоже уже было сказанно
    ps: а экземплов/демок по кросплатформенному программингу я например не встречал...