Модераторы: xvr
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Паралелльные TCP/UDP сервер, TCP UDP fork 
:(
    Опции темы
UserNet
Дата 18.9.2008, 21:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 226
Регистрация: 13.12.2006
Где: Новосибирск

Репутация: нет
Всего: 3



Доброго времение суток, пытаюсь написать сервер который работает по двум протоколам (TCP и UDP) параллельно, всё хорошо, но получается передать файл. В чём проблема?  smile 


Сервер
Код

#include <sys/types.h>
#include <sys/socket.h>
#include <sys/file.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include <stdio.h>
#include <pthread.h>

char * daytime() {
time_t now;
now=time(NULL);
return ctime(&now);
}
        
void * udp_thread(int * p_sock) {
int sock=*p_sock;
int bytes_read,fd;
for (;;) {
struct sockaddr from;
unsigned int len=sizeof(from);
char buf[81 ];
memset(buf,0,81);

bytes_read=recvfrom(sock,&buf,80,0,&from,&len);
printf("\n1\n");
printf("udp incomig:%s",buf);
fd=open(buf,O_WRONLY|O_CREAT|O_TRUNC);

while(1)
{
 printf("\n2\n");
 bytes_read=recvfrom(sock,&buf,80,0,&from,&len);
 printf("au %i",bytes_read);
 write(fd,buf,bytes_read);
 if (bytes_read<0) break;
 printf("udp incomig:%s",buf);

}
                          
memset(buf,0,81);
strncpy(buf,daytime(),80);
sendto(sock,buf,strlen(buf),0,&from,len);
puts("answer udp");
}
                                                    
return NULL;
}
                                                
void * tcp_thread(int *p_sock) {
   int sock=*p_sock;
   int bytes_read;
   
   
    for (;;) {
        int c_sock=accept(sock,NULL,NULL);
        char buf[81];
        memset(buf,0,81);
    bytes_read=recv(sock,buf,1024,0);
//    printf("\n1\n");
//    printf("\n%i",bytes_read);
    while (1)
    {
    bytes_read=recv(sock,buf,1024,0);

//    printf("\n%i",bytes_read);    
    if (bytes_read<0) break;    
    printf(buf);
    
    }        
//    printf("\n2\n");    
        strncpy(buf,daytime(),80);
        write(c_sock,buf,strlen(buf));
        shutdown(c_sock,0);
        close(c_sock);
//        puts("answer tcp");
    }
//    pthread_exit(NULL);
    return NULL;
}
                                                                                                
int main() {
struct sockaddr_in addr;
memset(&addr,0,sizeof(addr));
addr.sin_family=AF_INET;
addr.sin_port=htons(3425);
addr.sin_addr.s_addr=INADDR_ANY;
                                                                                                           
int sock;
const int threads=10;
pthread_t tid;
if ( fork() ) {
int i;
sock=socket(AF_INET,SOCK_STREAM,0);
bind(sock,(struct sockaddr *)&addr,sizeof(addr));
listen(sock,5);
for (i=0; i<threads; i++)
pthread_create(&tid,NULL,&tcp_thread,&sock);
}
else {
int i;
sock=socket(AF_INET,SOCK_DGRAM,0);
bind(sock,(struct sockaddr *)&addr,sizeof(addr));
for (i=0; i<threads; i++)
pthread_create(&tid,NULL,&udp_thread,&sock);
}
pthread_join(tid,NULL);
return 0;
}



Клиент TCP

Код

%:include <sys/socket.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/file.h>

char message[] = "test1.txt";
char buf[sizeof(message)];

int main()
{
printf("begin\n");
    int sock;
    struct sockaddr_in addr;
    int fd;
    char buff[BUFSIZ];
   
   printf("-1\n");
    fd=open("test1.txt",O_RDONLY);
        
    
    printf("0\n");
    sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if(sock < 0)
    {
        perror("socket");
        exit(1);
    }
    printf("1\n");
    addr.sin_family = AF_INET;
    addr.sin_port = htons(3425);
    addr.sin_addr.s_addr = htonl(0);
    if(connect(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0)
    {
        perror("connect");
        exit(2);
    }

    printf("2\n");
    send(sock, message, sizeof(message), 0);
    int n=0;
    while ((n=read(fd,buff,BUFSIZ))>0)
    {
       printf(buff);        
       send(sock, buff, n, 0);
    }
    recv(sock, buf, sizeof(message), 0);
    printf("3\n");    
    printf(buf);
    close(sock);

    return 0;
}



Клиент UDP
Код

%:include <sys/socket.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/file.h>

char message[] = "test1.txt";
//char buf[sizeof(message)];

int main()
{
    int sock;
    struct sockaddr_in addr;
    int fd;
    char buff[BUFSIZ];
   
    fd=open("test.txt",O_RDONLY);
        
    

    sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
    if(sock < 0)
    {
        perror("socket");
        exit(1);
    }

    addr.sin_family = AF_INET;
    addr.sin_port = htons(3425);
    addr.sin_addr.s_addr = htonl(0);
    if(connect(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0)
    {
        perror("connect");
        exit(2);
    }


    send(sock, message, sizeof(message), 0);
    int n=0;
    while ((n=read(fd,buff,BUFSIZ))>0)
    {
       printf(buff);        
       send(sock, buff, n, 0);
    }
//    recv(sock, buf, sizeof(message), 0);
    
//    printf(buf);
    close(sock);

    return 0;
}



А вот ссылка на оригинал статьи с которую брал за основу сервера
тут

Помогите пожалуйста а то я уже замучался.  smile  smile  smile 
PM MAIL   Вверх
vinick
Дата 18.9.2008, 23:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 285
Регистрация: 9.6.2005

Репутация: 4
Всего: 22



Цитата

В чём проблема?

читай что такое UDP и с чем его едят.
Код

bytes_read=recvfrom(sock,&buf,80,0,&from,&len);
printf("\n1\n");
printf("udp incomig:%s",buf);
fd=open(buf,O_WRONLY|O_CREAT|O_TRUNC);

в строке 1 у тебя после старта сервера сидит 10 потоков. В какой-то момент клиент шлет имя файла - "test1.txt", просыпается поток П1, читает это имя и создает файл. Пока он это делает, клиент шлет еще сообщение. Его перехватывает поток П2, в той же строке 1, т.е. он думает что тоже читает имя файла. ну и так далее в зависимости от threads и размера передаваемого файла. в итоге на диске получается каша. 

вот лог работы UDP части твоего сервера
Код

$ ls
fork_srv  fork_udp  test.txt
$ cat test.txt
hello
$ ./fork_srv

1
udp incomig:test1.txt
2

1
udp incomig:hello

2
^C
$ ls
fork_srv  fork_udp  hello?  test1.txt  test.txt


PM MAIL ICQ Jabber   Вверх
A1ukard
Дата 24.9.2008, 23:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 16
Регистрация: 19.3.2007

Репутация: нет
Всего: нет



    int n=0;
    while ((n=read(fd,buff,BUFSIZ))>0)
    {
       printf(buff);        
       send(sock, buff, n, 0);
    }

такое будет работать разве что на локалхосте и, если повезет, в локалке.
UDP пакеты могут теряться, приходить в произвольном порядке + один пакет может прийти несколько раз.

Решение следующее: (считаем что клиент получает файл от сервера) к каждому пакету цепляешь его номер или смещение данных в файле. на каждый полученный пакет клиент должен отправить подтверждение. Повторяющиеся пакеты должны игнорироваться как клиентом, так и сервером. Если от клиента во время не пришло подтверждение, пакет посылается снова. Для повышения производительности, клиент должен не дожидаясь подтверждения отправлять сразу несколько пакетов клиенту, а клиент слать несколько подтверждений одним пакетом, притом несколько раз, чтобы сервер не отправил все полученные части заново в случае потери подтверждения.

ЗЫ. Учти, что несмотря на то, что в UDP пакет физически может влезть до 64 Кб данных, гарантированно через все роутеры и шлюзы проходят только пакеты не длиннее 256-и байт (точно не помню, почитай про протокол DNS в RFC).
PM MAIL   Вверх
MAKCim
Дата 25.9.2008, 14:15 (ссылка) |  (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: 84
Всего: 207



Цитата(A1ukard @  24.9.2008,  23:15 Найти цитируемый пост)
гарантированно через все роутеры и шлюзы проходят только пакеты не длиннее 256-и байт (точно не помню, почитай про протокол DNS в RFC). 

с чего это вдруг?
и причем здесь DNS?


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
UserNet
Дата 26.9.2008, 08:53 (ссылка) |  (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 226
Регистрация: 13.12.2006
Где: Новосибирск

Репутация: нет
Всего: 3



А можно пример кода?  smile 
PM MAIL   Вверх
shara
Дата 12.10.2008, 21:45 (ссылка) |  (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 344
Регистрация: 29.6.2004
Где: печенье?

Репутация: нет
Всего: 2



A1ukard,
мне интересно, есть ли тогда смысл применять быстрый но не надёжный UDP и применять все эти повторные и многократные пересылки одной и той же информации... не получится ли медленнее чем TCP

обяснити пожалуйста или хотя бы ткните ссылкой

Это сообщение отредактировал(а) shara - 12.10.2008, 21:45


--------------------
   с точки зрения аэродинамики шмель не может летать  
PM MAIL   Вверх
Maka6er
Дата 15.10.2008, 23:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 150
Регистрация: 27.2.2007
Где: Киев

Репутация: нет
Всего: 3



Если надо передать файл или что то что гарантированно должно дойти то юзают TCP, но если надо передавать потоковые данные(видео, звук) в которых критична скорость доставки, а не надежность - UDP
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С/С++: Программирование под Unix/Linux"
xvr
  • Проставьте несколько ключевых слов темы, чтобы её можно было легче найти.
  • Не забывайте пользоваться кнопкой "Код".
  • Вопросы мобильной разработки тут
  • Телепатов на форуме нет! Задавайте чёткий, конкретный и полный вопрос. Указывайте полностью ошибки компилятора и компоновщика.
  • Новое сообщение должно иметь прямое отношение к разделу форума. Флуд, флейм, оффтопик запрещены.
  • Категорически запрещается обсуждение вареза, "кряков", взлома программ и т.д.

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, xvr.

 
 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Программирование под Unix/Linux | Следующая тема »


 




[ Время генерации скрипта: 0.1143 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.