Сокеты во FreeBSD...

Модератор: Fastman

Правила форума
Убедительная просьба юзать теги [code] при оформлении листингов.
Сообщения не оформленные должным образом имеют все шансы быть незамеченными.
paradox
проходил мимо
Сообщения: 11620
Зарегистрирован: 2008-02-21 18:15:41

Re: Сокеты во FreeBSD...

Непрочитанное сообщение paradox » 2008-11-20 22:04:14

Код: Выделить всё

g++ socket.cpp
./a.out
токо ошибки поисправляй

Код: Выделить всё

#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>
#include <syslog.h>
#include <signal.h>
#include <string.h>
#include <string>

using std::string;

class tcpdaemon
{
  protected:
    void daemonize();
    void mainloop();
    void operate(int fd);
    static void signalhandler(int signum);
  public:
    void exec();
};

void tcpdaemon::signalhandler(int signum)
{
  waitpid(0, 0, WNOHANG);
}

void tcpdaemon::daemonize()
{
  struct sigaction sa;
  printf("Welcome to Playback Price Server. Server start OK!\n");
  int pid = fork();
  switch(pid)
  {
    case 0:
    setsid();
    chdir("/");
    close(0);
    close(1);
    close(2);
    memset(&sa, 0, sizeof(sa));
    sa.sa_handler = &signalhandler;
    sigaction(SIGCHLD, &sa, 0);
    exit(0);
    case -1:
      printf("Fork error...\n");
      break;
    default:
      printf("OK. PID=%d\n", pid);
      break;
   }
}

void tcpdaemon::mainloop()
{
  int sockfd, fd;
  struct sockaddr_in sa;
  socklen_t n;
  sockfd = socket(PF_INET, SOCK_STREAM, 0);
  if(sockfd != -1)
  {
    memset(&sa, 0, sizeof(sa));
    sa.sin_family = AF_INET;
    sa.sin_addr.s_addr = htonl(INADDR_ANY);
    sa.sin_port = htons(21867);
    if(bind(sockfd, (struct sockaddr *)&sa, sizeof sa) != 1)
    {
      while(1)
      {
        if(!listen(sockfd, 50))
        {
          n = sizeof sa;
          if((fd = accept(sockfd, (struct sockaddr *)&sa, &n)) != -1)
          {
            printf("Connection from %s", inet_ntoa(sa.sin_addr));
            if(!fork)
            {
              operate(fd);
            }
          }
        }
      }
    }
  }
}

void tcpdaemon::operate(int fd)
{
  char c;
  bool finished;
  string cmd, answer;
  finished = false;
  write(fd, answer.c_str(), answer.size());
  while(!finished)
  {
    cmd = answer = "";
    while(!finished)
      finished = read(fd, &c, 1) != 1;
    if(c == '\n')
      break;
    else if(c != '\r')
      cmd += c;
    if(!finished && !cmd.empty())
    {
      if(cmd == "info")
        answer = "Welcome to PlayBack Price Server...";
      else if(cmd == "quit")
      {
        shutdown(fd, 2);
        close(fd);
        finished = true;
      }
    }
  }
  if(!finished && !answer.empty())
  {
    answer += "\n";
    write(fd, answer.c_str(), answer.size());
  }
  exit(0);
}

void tcpdaemon::exec()
{
  daemonize();
}


int main()
{
  tcpdaemon daemon;
  daemon.exec();
  return 0;
};

Хостинговая компания Host-Food.ru
Хостинг HostFood.ru
 

Услуги хостинговой компании Host-Food.ru

Хостинг HostFood.ru

Тарифы на хостинг в России, от 12 рублей: https://www.host-food.ru/tariffs/hosting/
Тарифы на виртуальные сервера (VPS/VDS/KVM) в РФ, от 189 руб.: https://www.host-food.ru/tariffs/virtualny-server-vps/
Выделенные сервера, Россия, Москва, от 2000 рублей (HP Proliant G5, Intel Xeon E5430 (2.66GHz, Quad-Core, 12Mb), 8Gb RAM, 2x300Gb SAS HDD, P400i, 512Mb, BBU):
https://www.host-food.ru/tariffs/vydelennyi-server-ds/
Недорогие домены в популярных зонах: https://www.host-food.ru/domains/

1SBMJJTG
проходил мимо

Re: Сокеты во FreeBSD...

Непрочитанное сообщение 1SBMJJTG » 2008-11-20 22:15:56

Спасибо - как раз то что я хотел.
Есть ли какой то мануал по функциям. Например мне надо получить дисковый обьем партиции или список процессов.

paradox
проходил мимо
Сообщения: 11620
Зарегистрирован: 2008-02-21 18:15:41

Re: Сокеты во FreeBSD...

Непрочитанное сообщение paradox » 2008-11-20 22:19:28

проще заглянуть на примеру реализаций утилит

Код: Выделить всё

top
du 
df
и дальше уже по функциям

Код: Выделить всё

man socket
итд имя подставляй токо


ток тот тцп сервер кажись неработает всеравно))
покрайней мере
после запуска
в сервисах я его ненашел

red
проходил мимо

Re: Сокеты во FreeBSD...

Непрочитанное сообщение red » 2008-11-20 22:25:25

И я скажу так после компиляции и запуске в списке процессов его нету

Аватара пользователя
hizel
дядя поня
Сообщения: 9032
Зарегистрирован: 2007-06-29 10:05:02
Откуда: Выборг

Re: Сокеты во FreeBSD...

Непрочитанное сообщение hizel » 2008-11-20 22:36:02

щитото я не вижу точку входа в mainloop
ну форкается у вас процесс и всё ...
В дурацкие игры он не играет. Он просто жуткий, чу-чу, паровозик, и зовут его Блейн. Блейн --- это Боль.

paradox
проходил мимо
Сообщения: 11620
Зарегистрирован: 2008-02-21 18:15:41

Re: Сокеты во FreeBSD...

Непрочитанное сообщение paradox » 2008-11-20 22:38:53

ну вставте там маинлуп в нужное место)
просто ломно

кстати это где то отсюда с форума пример брался
интересно откуда именно))

red
проходил мимо

Re: Сокеты во FreeBSD...

Непрочитанное сообщение red » 2008-11-20 22:46:05

Так все таки куда правильно mainloop вставить?

paradox
проходил мимо
Сообщения: 11620
Зарегистрирован: 2008-02-21 18:15:41

Re: Сокеты во FreeBSD...

Непрочитанное сообщение paradox » 2008-11-20 22:49:18

я на вашем месте когда еще незнал С/С++ такие ошибки за 3 секунды исправлял)
вопрос - зачем вам тогда тот код если вы в нем не разбираетесь?


Аватара пользователя
hizel
дядя поня
Сообщения: 9032
Зарегистрирован: 2007-06-29 10:05:02
Откуда: Выборг

Re: Сокеты во FreeBSD...

Непрочитанное сообщение hizel » 2008-11-21 0:01:20

хехе развратили меня перлы да питончеки, тыкнул исходник, запустил, получил зомбю :)
В дурацкие игры он не играет. Он просто жуткий, чу-чу, паровозик, и зовут его Блейн. Блейн --- это Боль.

red
проходил мимо

Re: Сокеты во FreeBSD...

Непрочитанное сообщение red » 2008-11-21 12:00:37

И все таки подскажиет пионеру куда праивльно вставить?

Аватара пользователя
zingel
beastie
Сообщения: 6204
Зарегистрирован: 2007-10-30 3:56:49
Откуда: Moscow
Контактная информация:

Re: Сокеты во FreeBSD...

Непрочитанное сообщение zingel » 2008-11-21 12:02:09

paradox писал(а):я на вашем месте когда еще незнал С/С++ такие ошибки за 3 секунды исправлял)
вопрос - зачем вам тогда тот код если вы в нем не разбираетесь?
скрипткид...
Z301171463546 - можно пожертвовать мне денег

red
проходил мимо

Re: Сокеты во FreeBSD...

Непрочитанное сообщение red » 2008-11-21 12:48:53

Так все таки чтобы закрыть вопрос - куда праивльно вставить mainloop()
У меня никак не получается заставить его работаьт как демон.

Аватара пользователя
hizel
дядя поня
Сообщения: 9032
Зарегистрирован: 2007-06-29 10:05:02
Откуда: Выборг

Re: Сокеты во FreeBSD...

Непрочитанное сообщение hizel » 2008-11-21 12:55:49

в демонизе перед exit(0) канешно :no:
В дурацкие игры он не играет. Он просто жуткий, чу-чу, паровозик, и зовут его Блейн. Блейн --- это Боль.

red
проходил мимо

Re: Сокеты во FreeBSD...

Непрочитанное сообщение red » 2008-11-21 13:14:44

Спасибо громадное помогло.
А кто нибудь подскажет мне ребенку Майкрософта какой нибудь консольные редактор с возможностью дебага для FreeBSD?

Аватара пользователя
hizel
дядя поня
Сообщения: 9032
Зарегистрирован: 2007-06-29 10:05:02
Откуда: Выборг

Re: Сокеты во FreeBSD...

Непрочитанное сообщение hizel » 2008-11-21 13:21:43

emacs
В дурацкие игры он не играет. Он просто жуткий, чу-чу, паровозик, и зовут его Блейн. Блейн --- это Боль.

red
проходил мимо

Re: Сокеты во FreeBSD...

Непрочитанное сообщение red » 2008-11-21 13:59:45

if(!fork)
{
operate(fd);
}
Простите мне мою тупость но
1.Разве operate(fd); когда либо запустится если даже компилдятор при компиляции говорит the address of 'pid_t fork()' will always evaluate as 'true'
2.Как ограничить запуск толкьо 1 копией демона.
3. Из области фантастики- sa.sin_port = htons(6282);
if(bind(sockfd, (struct sockaddr *)&sa, sizeof sa) != 1)
Иногда при запуске получаю что открыт порт не 6282 а наприемр 51357 или 55897 (смотрею по netstat -na ) почему? Копилю gcc 4.3.2 FreeBSD 7.0

red
проходил мимо

Re: Сокеты во FreeBSD...

Непрочитанное сообщение red » 2008-11-21 15:23:18

Мы стоили стоили и наконец построили - может комуто пригодится. Из улучшений проверка на запуск толкьо 1 копии сервиса (если ктонибудь придумает более изящное решение буду только рад). Поправил вызов форка (переь на порт можете конектится скоко угодно).
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>
#include <syslog.h>
#include <signal.h>
#include <string.h>
#include <string>
#include <fcntl.h>
#include <signal.h>

using std::string;

#define RUNNING_DIR "/tmp"
#define LOCK_FILE "exampled.lock"
#define LOG_FILE "exampled.log"

class tcpdaemon
{
protected:
void daemonize();
void mainloop();
void operate(int fd);
static void signalhandler(int signum);
public:
void exec();
};

void tcpdaemon::signalhandler(int signum)
{
waitpid(0, 0, WNOHANG);
}
void tcpdaemon::daemonize()
{
int i,lfp;
struct sigaction sa;
int pid = fork();
switch(pid)
{
case 0:
setsid();
for (i=getdtablesize();i>=0;--i) close(i); /* close all descriptors */
i=open("/dev/null",O_RDWR); dup(i); dup(i); /* handle standart I/O */
chdir(RUNNING_DIR); /* change running directory */
lfp=open(LOCK_FILE,O_RDWR|O_CREAT,0640);
if (lfp<0) exit(1); /* can not open */
if (lockf(lfp,F_TLOCK,0)<0) exit(0); /* can not lock */
chdir("/");
close(0);
close(1);
close(2);
memset(&sa, 0, sizeof(sa));
sa.sa_handler = &signalhandler;
sigaction(SIGCHLD, &sa, 0);
mainloop();
exit(0);
}
}
void tcpdaemon::mainloop()
{
int sockfd, fd;
string welc;
struct sockaddr_in sa;
socklen_t n;
pid_t pid;

sockfd = socket(PF_INET, SOCK_STREAM, 0);
if(sockfd != -1)
{
memset(&sa, 0, sizeof(sa));
sa.sin_family = AF_INET;
sa.sin_addr.s_addr = htonl(INADDR_ANY);
sa.sin_port = htons(6282);
if(bind(sockfd, (struct sockaddr *)&sa, sizeof sa) != 1)
{
if(!listen(sockfd, 50))
{
while(1)
{
n = sizeof sa;
if((fd = accept(sockfd, (struct sockaddr *)&sa, &n)) != -1)
{
if((pid=fork())==0)
{
operate(fd);
}
else if (pid > 0)
close(fd);
}
}
}
}
}
}
void tcpdaemon::operate(int fd)
{
char c;
bool finished;
string cmd, answer;
finished = false;
answer="test";
write(fd, answer.c_str(), answer.size());
while(!finished)
{
cmd = answer = "";
while(!finished)
finished = read(fd, &c, 1) != 1;

if(c == '\n')
break;
else if(c != '\r')
cmd += c;
if(!finished && !cmd.empty())
{
if(cmd == "info")
answer = "Welcome to PlayBack Price Server...";
else if(cmd == "quit")
{
shutdown(fd, 2);
close(fd);
finished = true;
}
}
}
if(!finished && !answer.empty())
{
answer += "\n";
write(fd, answer.c_str(), answer.size());
}
exit(0);
}

void tcpdaemon::exec()
{
daemonize();
}

int main()
{
tcpdaemon daemon;
daemon.exec();
return 0;
};