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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Простой чат-сервер 
:(
    Опции темы
iAloha
Дата 8.2.2010, 12:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Доброе время суток!
Вообщем так.... 
Сервер
Код

#include <stdio.h>
#include <stdlib.h>
#include<string.h>
#include <errno.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include<netinet/in.h>
#include <arpa/inet.h>
int GetPort(const char *str);
void Usage();
void Error(const char *msg);
void Work(int sock);

int main (int argc, char **argv)
{
    int port;
    int sock;
    int retcode;
    struct sockaddr_in sa;
    if(argc!=2 || strcmp(argv[1],"-h")==0)
    {
        Usage();
    }
    port=GetPort(argv[1]);
    printf("Запускаю сервер на порту %d\n",port);
    sock=socket(PF_INET,SOCK_STREAM,IPPROTO_TCP);
    if(sock==-1)
    {
        Error ("Не могу создать сокет");
    }
    memset(&sa,0,sizeof(sa));
    sa.sin_family=AF_INET;
    sa.sin_addr.s_addr=INADDR_ANY;
    sa.sin_port=htons(port);
    retcode=bind(sock,(struct sockaddr*) (&sa),sizeof(sa));
    if(retcode==-1)
    {
        Error("Ошибка привязи сокета к ip адрусу и номкру порта");
    }
    retcode=listen(sock,10);
    if(retcode==-1)
    {
        Error("Ощшибка перевода сокета в пассивное состояние");
    }
    Work(sock);
    close(sock);
    return 0;
}

int GetPort(const char *str)
{
    int port;
    port=atoi(str);
    if(port<1||port>65535)
    {
        Error("Магическое число должно быть в диапозоне");
    }
    return port;
}

void Work(int sock)
{
    fd_set ourfds;
    fd_set readfds;
    char buf[8192];
    int len;
    int retcode;
    int sock2;
    int sock3;
    char list [1024];
    socklen_t size;
    struct sockaddr_in sa;
    FD_ZERO(&ourfds);
    while (42==42)
    {
        FD_ZERO(&readfds);
        readfds=ourfds;
        FD_SET(sock,&readfds);
        retcode=select(FD_SETSIZE,&readfds,NULL,NULL,NULL);
        if (retcode==-11)
        {
            Error("Ошибка select");
        }
    
        if (FD_ISSET(sock,&readfds))
        {
            sock2=accept(sock,(struct sockaddr*)(&sa),&size);
            if (sock2==-1)
            {
                Error("Ошибка получения адреса пользователя");
            }
            printf("Приняли соединение с адреса%s\n",inet_ntoa(sa.sin_addr));
            FD_SET(sock2,&ourfds);
        }

        for (sock2=0; sock2<FD_SETSIZE;sock2++)
        {
            if(FD_ISSET(sock2,&ourfds) && FD_ISSET(sock2,&readfds))
            {
                len=read(sock2,buf,sizeof(buf));
                if(len<0)
                {
                    printf("Ошибка чтения сокета");
                    FD_CLR(sock2,&ourfds);
                }
                else if(len==0)
                {
                    printf("Клиент %s закрыл соединение\n",inet_ntoa(sa.sin_addr));
                    FD_CLR(sock2,&ourfds);
                }
                else
                {
                    buf[len]=0;
                    if(getsockname(sock,(struct sockaddr*)(&sa),&size)==-1)
                    {
                        printf("Error getsockname\n");
                    }
                    printf("Получили с адреса %s: %s\n",inet_ntoa(sa.sin_addr),buf);
                    if (buf[0]=='s')
                    {
                        sock3=atoi(buf+1);
                        write(sock3,buf,len);
                    }
                    else if (buf[0]=='l')
                    {
                        for(sock3=0; sock3<FD_SETSIZE; sock++)
                        {
                            if(FD_ISSET(sock3,&ourfds))
                            {
                                sprintf(list,"Список подключенных пользователей\n%d\n",sock3);
                                write(sock2,list,strlen(list));
                            }
                        }
                    }
                    else
                    {
                        sprintf(list,"Уважаемый клиент. Нет такой команды!!!\n");
                        write(sock,list,strlen(list));
                    }
                }
            }
        }
    }
}

void Usage()
{
    fprintf(stderr,"Запускать как: ./server port.\n");
    exit(-1);
}

void Error(const char *msg)
{
    fprintf(stderr,"Ошибка: %s(%s)\n",msg,strerror(errno));
    exit(-1);
}


Клиент
Код

#include <stdio.h>
#include<stdlib.h>
#include<string.h>
#include<errno.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<netdb.h>
int GetPort(const char *str);
void Usage();
void Error(const char *msg);
int Talk(int sock);
int main(int argc, char **argv)
{
    int port;
    int sock;
    int retcode;
    struct sockaddr_in servaddr;
    struct hostent *host;
    if(argc!=3|| strcmp(argv[1],"-h")==0)
    {
        Usage();
    }
    port=GetPort(argv[2]);
    printf("Запускаю клиент на порту %d\n",port);
    sock=socket(PF_INET,SOCK_STREAM,IPPROTO_TCP);
    if (sock==-1)
    {
        Error("Не могу создать сокет");
    }
    memset(&servaddr,0,sizeof(servaddr));
    servaddr.sin_family=AF_INET;
    servaddr.sin_port=htons(port);
    host=gethostbyname(argv[1]);
    if  (host==0)
    {
        Error("Не верный IP");
    }
    servaddr.sin_addr.s_addr=*(unsigned long*)(host->h_addr);
    retcode=connect(sock,(struct sockaddr*)&servaddr,sizeof(servaddr));
    if (retcode==-1)
    {
        Error("Ошибка подключения");
    }
    Talk(sock);
    close(sock);
    return 0;
}
int GetPort(const char *str)
{
    int port;
    port=atoi(str);
    return port;
}

int Talk(int sock)
{
    char buf[81920];
    int len = -1;
    int retcode;
    fd_set readfds;
    while (42 == 42)
    {
        FD_ZERO(&readfds);
        FD_SET(sock, &readfds);
        FD_SET(0, &readfds);
        retcode=select(1024, &readfds, 0, 0, 0);
        if(retcode==-1)
        {
            Error("Ошибка select");
        }
        else
        {
            if(FD_ISSET(sock, &readfds))
            {
                len=read(sock, buf, sizeof(buf));
                if(len < 0)
                {
                    Error("Ошибка чтения сокета");
                }
                else if (len == 0)
                {
                    printf("Сервер закрыл соединение\n");
                    return 0;
                }
                else
                {
                    buf[len] = 0;
                    printf("Получил с сервера: %s\n",buf);
                }
            }
            if(FD_ISSET(0,&readfds))
            {
                len=read(0, buf, sizeof(buf));
                if(len<0)
                {
                    Error("Ошибка чтения");
                }
                else if (len==0)
                {
                    printf("Сервер закрыл соединение\n");
                    return 0;
                }
                else
                {
                    buf[len]=0;
                    retcode=write(sock,buf,len);
                    if(retcode==-1)
                    {
                        Error("Ошибка отправки");
                    }
                    else
                    {
                        printf("Отправил на сервер: %s\n",buf);
                    }
                }
            }
        }
    }
}

void Usage()
{
    fprintf(stderr,"Запускать как ./client ip port.\n");
    exit(-1);
}

void Error(const char *msg)
{
    fprintf(stderr,"Ошибка:%s(%s)\n",msg,strerror(errno));
    exit(-1);
}


Запускать так: ./server 1234
./client localhost 1234

Что то подобное тут уже выкладывалось, но тема забылась и всё.... Проблемe той темы я решил, но у меня возникла новая, а точнее вопрос : как сделать возможность постоянного принятия данных параллельно с отправкой?


PM MAIL   Вверх
MAKCim
Дата 8.2.2010, 19:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



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


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

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

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

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


 




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


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

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