The OpenNET Project / Index page

[ новости /+++ | форум | теги | ]

форумы  помощь  поиск  регистрация  майллист  вход/выход  слежка  RSS
"Ошибка connect() в мультипроцессном приложении"
Вариант для распечатки  
Пред. тема | След. тема 
Форумы Программирование под UNIX (Public)
Изначальное сообщение [ Отслеживать ]

"Ошибка connect() в мультипроцессном приложении"  
Сообщение от nkk (ok) on 20-Сен-08, 11:21 
В общем это мультипроцессный сервер, призванный ретранслировать аудиопоток. Написал как попало, и оно немножко работает. Помогите разобраться в глюках.
Принцип работы: порождается клиентский процесс, соединяющийся с аудио каналом 128 кб/с и читающий оттудова данные без метаинформации и заносящий их в общий буфер;
затем, при подключении клиентов, им отдается содержимое этого буфера.

Проще для себя способа синхронизации, чем изменение общей переменной, не нашел, возможно он глюкавый.

[gpk@localhost server]$ ./serv 10.25.250.1 / 8000 9988
Rebroadcastinf 128 kbps mp3 stream without metadata
listener 2: Invalid argument
[gpk@localhost server]$ op
op
op
op

Возникает ошибка Invalid argument в родительском прцессе и он завершается, в то время, как порожденный клиент работает некоторое время, получая данные, но потом, все равно, отрубается.

server.c

#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#include <sys/types.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <sys/ipc.h>
#include <sys/shm.h>

#include <netinet/in.h>
#include <arpa/inet.h>
#include <signal.h>

#define SERVER_PORT 9999
#define LINE_SPEED 128

const unsigned int BFFER_LEN = LINE_SPEED / 8 * 100

int main( int argc, char* argv[] ){
  printf( "Rebroadcastinf 128 kbps mp3 stream without metadata\n" );

  if( argc != 5 ){
    printf( "%s stream_ip /stream_path stream_port local_port\n\n", argv[0] );
    return 1;
  }

  int listener, k;
  struct sockaddr_in addr;
  char buf[BFFER_LEN], ch;

  if( ( listener = socket( AF_INET, SOCK_STREAM, 0 ) ) < 0 )
    exit( 1 );

  addr.sin_family = AF_INET;

  int shfd_buf = shmget( IPC_PRIVATE, BFFER_LEN, IPC_CREAT | S_IRWXU | S_IRWXG | S_IRWXO );
  if( shfd_buf == -1 )
    return 1;
  int shfd_blink = shmget( IPC_PRIVATE, 1, IPC_CREAT | S_IRWXU | S_IRWXG | S_IRWXO );
  if( shfd_blink == -1 )
    return 1;

  switch( fork() ){                              // === 1 ===
  case -1: perror("fork");break;
  case 0:
    char* sh_buf = (char*) shmat( shfd_buf, 0, 0 );
    if( sh_buf == (char*) -1 ){
      perror("sh_buf w");
      exit( 2 );
    }
    char* sh_blink = (char*) shmat( shfd_blink, 0, 0 );
    if( sh_blink == (char*) -1 ){
      perror("sh_blink w");
      exit( 2 );
    }

    addr.sin_port = htons( atoi( argv[3] ) );
    addr.sin_addr.s_addr = inet_addr( argv[1] );
    if( connect( listener, (struct sockaddr *) &addr, sizeof( addr ) ) < 0 ){
      printf( "%s:%s\n" , argv[1], argv[3] );
      perror( "connect" );
      exit( 2 );
    }

    strcpy( buf, "GET " );
    strncat( buf, argv[2], strlen( argv[1] ) );
    strcat( buf, " HTTP/1.0\nUser-Agent: WinampMPEG/5.53\nAccept: */*Icy-MetaData:0\nConnection: close\n\n" );

    send( listener, buf, strlen( buf ), 0 );
    while( recv( listener, &ch, 1, 0 ) > 0 ){
      strncat( buf, &ch, 1 );
      if( strlen( buf ) < BFFER_LEN )
        continue;
      strcpy( sh_buf, buf );
      strcpy( sh_blink, strcmp( "1", sh_blink ) ? "1" : "0" );
      buf[0] = '0';
      printf( "op\n" );
      sleep(1);
    }
    shmdt( sh_buf );
    shmdt( sh_blink );
    close( listener );
    _exit( 0 );
  }                                              // === 1 ===

  int sock;
  addr.sin_port = htons( atoi( argv[4] ) );
  addr.sin_addr.s_addr = INADDR_ANY;

  if( bind( listener, (struct sockaddr *) &addr, sizeof( addr ) ) < 0 ){
    perror("listener 2");
    exit( 2 );
   }
  listen( listener, 5 );
  signal(SIGCHLD, SIG_IGN);


    printf( "------------\n" );
    fflush( stdout );


  char* sh_buf = (char*) shmat( shfd_buf, 0, SHM_RDONLY );
  if( sh_buf == (char*) -1 )
    return 1;
  char* sh_blink = (char*) shmat( shfd_blink, 0, 0 );
  if( sh_blink == (char*) -1 )
    return 1;
  char tmp;

  while( 1 ){
    sock = accept( listener, NULL, NULL );
    if( sock < 0 ){
      perror( "accept" );
      exit( 3 );
    }
    switch( fork() ){
    case 0:
      close(listener);

      printf( "user connected\n" );
      strcpy( buf, "ICY 200 OK\nicy-name: First Radio Project\n\n" );
      while( recv( sock, &ch, 1, 0 ) > 0 );
      send( sock, buf, strlen( buf ), 0 );
      while( 1 ){
        while( !strncmp( &tmp, sh_blink, 1 ) );
        strncpy( &tmp, sh_blink, 1 );
        send( sock, sh_buf, BFFER_LEN, 0 );
      }

      shmdt( sh_buf );
      close( sock );
      _exit( 0 );
    default:
      close( sock );
    }
  }

  close( listener );
  return 0;
}


Высказать мнение | Ответить | Правка | Cообщить модератору

 Оглавление

Сообщения по теме [Сортировка по времени | RSS]


1. "Ошибка connect() в мультипроцессном приложении"  
Сообщение от NuINu (??) on 22-Сен-08, 15:57 
>В общем это мультипроцессный сервер, призванный ретранслировать аудиопоток. Написал как попало, и
>оно немножко работает. Помогите разобраться в глюках.

А у тебя не плохое чувство юмора! :)

Первая ошибка: плохое документирование исходника ======1=====  это не коментарий.

касаемов вылета, сделайте два! сокета и два раза вызовите socket
и для первого через который вы гет посылаете измените название.

strncat( buf, argv[2], strlen( argv[1] ) );
это ерунда какаято.

strcpy( sh_blink, strcmp( "1", sh_blink ) ? "1" : "0" );
при всей ненужности этого кода, вы выделили 1 байт, а копируете 2.
надо как то так:
*sh_blink = (*sh_blink == '1' ?'1':'0');

самое главное нет концепции как все это должно правильно работать.
вот почитайте про семафоры думаю поможет http://www.codenet.ru/progr/cpp/7/3.php

главное: когда начинает писать в шару поставщик контента, все реады должны быть закончены и новые блокироваться.
для этого нужно два семафора, один для всех читателей, которые могут начинать чтение только когда писатель закончит заполнение буфера.
второй для писателя, который может писать в буфер когда все читатели его освободят.

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

2. "Ошибка connect() в мультипроцессном приложении"  
Сообщение от NuINu (??) on 22-Сен-08, 16:02 

>strcpy( sh_blink, strcmp( "1", sh_blink ) ? "1" : "0" );
>при всей ненужности этого кода, вы выделили 1 байт, а копируете 2.

пардон, там не в байтах а в страницах выделяется. упустил.

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

3. "Ошибка connect() в мультипроцессном приложении"  
Сообщение от nkk (ok) on 07-Окт-08, 19:39 
[b]NuINu,[/b] Спасибо ;-)
Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

4. "Ошибка connect() в мультипроцессном приложении"  
Сообщение от NuINu (??) on 07-Окт-08, 22:26 
>[b]NuINu,[/b] Спасибо ;-)

Собственно, не зачто :)
простая отсылка к семаформа вряд ли сильно поможет, там надо релизовывать алогоритм один писатель несколько читателей, я у хассан гома, видел подобный, на 3 семафорах.
но мой алгоритм работает аж на 4 х :), работает в тестах, скажем так показывает нормальную синхронную работу(отставшие задачи, пропускают буфер), правда сетевую версия я не доделал, некогда.

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

Архив | Удалить

Индекс форумов | Темы | Пред. тема | След. тема
Оцените тред (1=ужас, 5=супер)? [ 1 | 2 | 3 | 4 | 5 ] [Рекомендовать для помещения в FAQ]




Партнёры:
PostgresPro
Inferno Solutions
Hosting by Hoster.ru
Хостинг:

Закладки на сайте
Проследить за страницей
Created 1996-2024 by Maxim Chirkov
Добавить, Поддержать, Вебмастеру