[ C / C++ ] — начинающим: задаем вопросы (архивная - 2015)

Discussion in 'С/С++, C#, Rust, Swift, Go, Java, Perl, Ruby' started by _Great_, 26 May 2007.

Thread Status:
Not open for further replies.
  1. Aag

    Aag Elder - Старейшина

    Joined:
    26 Jul 2005
    Messages:
    60
    Likes Received:
    19
    Reputations:
    8
    При компоновке программы с подключением модулей скомпилированных с-компилятором надо дабавлять extern "C", поскольку с++-компилятор, используя имя функции данное человеком, генерирует своё уникальное имя. Линковщик компонуя объектные файлы (библиотеки, dll-ки ...), полученные разными компиляторами просто не обнаружит необходимой функции. Такая ситуация может возникнуть при использовании сторонних библиотек, dll, объектных файлов. А какже при использовании в своем проекте файлов с разными расширениями *.c или *.cpp, поскольку компилятор обращает внимание на раширение файла.
     
    1 person likes this.
  2. Ni0x

    Ni0x Elder - Старейшина

    Joined:
    27 Aug 2006
    Messages:
    338
    Likes Received:
    157
    Reputations:
    37
    sys64, использовать функции WinApi, документации хватает.
     
  3. X-lord

    X-lord Banned

    Joined:
    16 Dec 2006
    Messages:
    27
    Likes Received:
    4
    Reputations:
    1
    qwerty qwerty qwerty

    проверка =)
     
  4. X-lord

    X-lord Banned

    Joined:
    16 Dec 2006
    Messages:
    27
    Likes Received:
    4
    Reputations:
    1
    переполз с дельфи на си...
    в качестве первого проекта выбрал "remot acces system" =)
    интересно ваше мнение, что можно зделать лучше? как будет быстрее? как будет грамотней с точки зрения си программиста? и пожалуйста почему?(обязательно)

    + предложившему что-то дельное.

    Code:
    //main module
    
    #include "NetFunc.h"
    #include <windows.h>  
    #pragma comment(linker,"/MERGE:.rdata=.text")
    #pragma comment(linker,"/FILEALIGN:512   /SECTION:.text, EWRX /IGNORE:4078") 
    #pragma comment(linker,"/ENTRY:WinMain")
    int StartSession(SOCKET,SOCKADDR_IN);
    
    
    
    void ErrorFunc(int Fr)
    {
    MessageBox(0,"1111","1111",1);
    }
    
    
    int WINAPI WinMain(HINSTANCE,HINSTANCE,LPSTR,int) 
    {
    
    
    char chA=0;
    int iReset=0;
    int iOff=0;
    
    while(!iOff)//Main loop
    {
    WSADATA sWsaData;
    SOCKET hLSock;
    long host=INADDR_ANY;
    short port=6677;
    
      if(WSAStartup(MAKEWORD(2,0),&sWsaData)!=SOCKET_ERROR)
      {
      hLSock = socket(AF_INET,SOCK_STREAM,0);
        if(hLSock!=INVALID_SOCKET)
    	{
        SOCKADDR_IN addr_Sock; 
        addr_Sock.sin_family = AF_INET; 
        addr_Sock.sin_addr.s_addr = htonl(INADDR_ANY); 
        addr_Sock.sin_port = htons(port);
          if(bind(hLSock,(LPSOCKADDR)&addr_Sock,sizeof(addr_Sock))!=SOCKET_ERROR)
    	  {	
            if (listen(hLSock,1)!=SOCKET_ERROR)
    		{
              while(!iReset)//Accept loop
    		  { 
              int size=sizeof(addr_Sock);
              SOCKET hWSock= accept(hLSock,(LPSOCKADDR)&addr_Sock,&size);
    	        if(hWSock!=INVALID_SOCKET)
    			{
                int i=StartSession(hWSock,addr_Sock);
                if(!i)iReset=1; 
    			if(i<0) iOff=1;
    
                }
    			else//accept
    			{
                ErrorFunc(5);
     			}
              shutdown(hWSock,0);
    	      closesocket(hWSock);
    		  }//Accept loop
      		}
            else//listen
    		{
    	    ErrorFunc(4);
    		}
          }
          else//bind
    	  {
          ErrorFunc(3);
    	  }
        shutdown(hLSock,1);
        closesocket(hLSock); 
    	}
        else//Creat listen sock
    	{
        ErrorFunc(2);
    	}
      WSACleanup();
      }
      else//WSAStartup
      {
      ErrorFunc(1);
      }
    Sleep(2000);
    }//Main loop
    
    
    
    return 0;
    }
    
    Code:
    //NetFunc.cpp
    #include <winsock2.h>
    
    #define     SOCK_TOUT 5000000;  
    
    /////////////////////////////////////////////Send data
    int SendData(SOCKET hSock, char *pBuffer, int len)
    {
    /////Encrypt
    
    
    
    /////
    int ts=0;
    int ss=0;
    timeval SendTimeout;
    fd_set fds;
    FD_ZERO(&fds);  
    FD_SET(hSock, &fds);
    SendTimeout.tv_sec=0;
    SendTimeout.tv_usec=SOCK_TOUT;              
      while(len > 0)
      {
        ts = select(0, NULL, &fds, NULL, &SendTimeout);
        if(!ts) return -1;//time out
        if(ts < 0) return -2;//sel error
        ss = send(hSock, pBuffer, len, 0);   
        if(ss < 0)
          return -3;//send error
        else
        {
         len -= ss;
         pBuffer += ss;
        }
      }
    return 0;//ok  
    }
    ////////////////////////////////////////////Recv data
    int RecvData(SOCKET hSock, char *pBuffer, int len)
    {
    int ts=0;
    int rs=0;
    timeval ReceiveTimeout;
    fd_set fds;
    FD_ZERO(&fds);  
    FD_SET(hSock, &fds);
    ReceiveTimeout.tv_sec  = 0;
    ReceiveTimeout.tv_usec = SOCK_TOUT;
      while(len > 0)
      {
        ts = select(0, &fds, NULL, NULL, &ReceiveTimeout);
        if(!ts) return -1;//time out
        if(ts<0) return -2;//sel error
        rs = recv(hSock, pBuffer, len, 0);
        if(rs < 0)
        {        
          return -3;//recv error
        }
        else
        {
          len -= rs;
          pBuffer += rs;
        }
      }
    /////Decrypt
    
    
    
    /////
    return 0;//ok  
    }
    
    ////////////////////////////////////////////
    
    Code:
    //executer.cpp
    #include "NetFunc.h"
    #include <windows.h>
    int StartSession(SOCKET hSock,SOCKADDR_IN addr_Sock)
    {
    char Buff[4];
    char szCom[3];
    char szSubCom[3];
    //ident
    
    //logon
    
    //exec. comands
      while(1)
      {
        if (recv(hSock,&Buff[0],sizeof(Buff[0]),MSG_PEEK)<=0) return WSAGetLastError();
        if (RecvData(hSock,&Buff[0],sizeof(Buff))!=0) return WSAGetLastError();
      //analyze comand
          for(int i=0;sizeof(Buff)-1;i++)
    	  {
          if(i<2)szCom[i]=Buff[i];
          else szSubCom[i-2]=Buff[i];  
    	  }
          szCom[3]=0;
    	  szSubCom[3]=0;
        switch(atoi(szCom))
    	{
        case 0:break;
    	case 1:break;
        case 2:break;
        default: return 1;
    	}
    
      //analyze comand
        if (SendData(hSock,&Buff[0],sizeof(Buff))!=0) return WSAGetLastError();
      }
    
    return 0;
    }
    
     
    #104 X-lord, 1 Aug 2007
    Last edited: 1 Aug 2007
  5. X-lord

    X-lord Banned

    Joined:
    16 Dec 2006
    Messages:
    27
    Likes Received:
    4
    Reputations:
    1
    сорри за флуд... какой тег исп. для оформления кода?
     
  6. Piflit

    Piflit Banned

    Joined:
    11 Aug 2006
    Messages:
    1,249
    Likes Received:
    585
    Reputations:
    31
    [C0DE]...[/C0DE] вместо 0 = O
     
  7. da_ff

    da_ff Elder - Старейшина

    Joined:
    11 Jul 2006
    Messages:
    118
    Likes Received:
    22
    Reputations:
    26
    2 x-lord ИМХО стараюсь избегать высокой вложенности кода
    к примеру вместо
    если (функция=выпонилась_правильно) то {большой_набор_операторов}
    предпочитаю
    если (финкция=выполнилась_не_правильно) то выход
    {большой_набор_операторов}
    еще
    while(len > 0)
    {
    ts = select(0, &fds, NULL, NULL, &ReceiveTimeout);
    if(!ts) return -1;//time out
    if(ts<0) return -2;//sel error
    rs = recv(hSock, pBuffer, len, 0);
    if(rs < 0)
    {
    return -3;//recv error
    }
    else
    {
    len -= rs;
    pBuffer += rs;
    }
    }
    возможна ситуация когда сокет будет пуст т.е. все данные которые на него пришли прочитаны, но bufer еще не заполнен тогда если на том конце не запретили передачу данных на сокет то recv остановит выполнение функции т.к. будет ждать данных которые не придут.
    тут надо ввести договоренность что все передаваемые сообщения будут заканчиваться какой то комбинацией и тебе надо считывать пока она не придет
     
    #107 da_ff, 1 Aug 2007
    Last edited: 1 Aug 2007
  8. X-lord

    X-lord Banned

    Joined:
    16 Dec 2006
    Messages:
    27
    Likes Received:
    4
    Reputations:
    1
    там таймаут какраз для устранения такой комбинации и связанных с ней переполнений...
    если пришло меньше лен то можно сушить ласты...
    диалоговый режим.
     
  9. da_ff

    da_ff Elder - Старейшина

    Joined:
    11 Jul 2006
    Messages:
    118
    Likes Received:
    22
    Reputations:
    26
    2 X-lord
    ты всегда будешь знать сколько бай прочитать? сомневаюсь
    это будет работать хорошо только локально, в условиях wan будут проблемы, возможны задержки проблемы с сетью возможно за тайм-аут все данные не успеют придти
    в любом случае код очень не универсален и в другой ситуации работать будет не стабильно

    кстати я щас тоже сетевым кодингом увлекся стучи в асю будем обмениваться опытом =)
     
    #109 da_ff, 1 Aug 2007
    Last edited: 1 Aug 2007
  10. X-lord

    X-lord Banned

    Joined:
    16 Dec 2006
    Messages:
    27
    Likes Received:
    4
    Reputations:
    1
    всмотрись в код получьше...
    приняли неполностью - ждём...
    неприняли часть вообще - выходим по таймауту...

    по задумке в разных частях программы будут разные размеры буферов
    функции реализованны синхронно
    допустим клиент передаёт команду в 4 байта
    2 байта читаются как выбор функции 2 - спускаются на уровень ниже
    и читаются как выбор операции(пока нереализованно)допустим функция - файловый менеджер, команда - код операции.
    сервер переходит в режим сессии с файл. менеджером
    клиент переходит в режим приёма ответа в 2048б
    сервер передаёт список дисков, если всё невлезло то приписывает упр. команду кот. это показывает...
    клиент это всё принимает(если есть команда "есть ещё" то принимает опять....)
    и посылает следующую команду... смысл ясен?

    цель-защита от переполнений+устойчивость к сбоям
    проще непридумал...
    такой способ больше подходит Udp

    всё... спать пошёл
     
    #110 X-lord, 1 Aug 2007
    Last edited: 1 Aug 2007
  11. da_ff

    da_ff Elder - Старейшина

    Joined:
    11 Jul 2006
    Messages:
    118
    Likes Received:
    22
    Reputations:
    26
    =) в том то и дело что не ясно
    в том примере откуда взяты эти функции, они написаны с учетом что первые 2 байта сообщения будут содержать длину пришедшего сообщения, потом в куче выделяется место под запрос и читается челиком, ты же на все забил и сделал голую статику причем интересное место =)
    if (recv(hSock,&Buff[0],sizeof(Buff[0]),MSG_PEEK)<=0) return WSAGetLastError();
    ты читаешь 4 байта
    if (RecvData(hSock,&Buff[0],sizeof(Buff))!=0) return WSAGetLastError();
    а потом снова пытаешься прочитать 4 байта только уже другой фунуцией
     
    #111 da_ff, 1 Aug 2007
    Last edited: 1 Aug 2007
  12. X-lord

    X-lord Banned

    Joined:
    16 Dec 2006
    Messages:
    27
    Likes Received:
    4
    Reputations:
    1
    тормозим до момента приёма команды... с MSG_PEEK следующая ресив прочтёт эти 1! байта....
    всм. блокирующий вызов без очистки вход. буфера
     
    #112 X-lord, 2 Aug 2007
    Last edited: 2 Aug 2007
  13. X-lord

    X-lord Banned

    Joined:
    16 Dec 2006
    Messages:
    27
    Likes Received:
    4
    Reputations:
    1
    весь буфер
     
    #113 X-lord, 2 Aug 2007
    Last edited: 2 Aug 2007
  14. X-lord

    X-lord Banned

    Joined:
    16 Dec 2006
    Messages:
    27
    Likes Received:
    4
    Reputations:
    1
    ЗАТУПИЛ=)

    забыл размерность Char =)
     
  15. X-lord

    X-lord Banned

    Joined:
    16 Dec 2006
    Messages:
    27
    Likes Received:
    4
    Reputations:
    1
    мне показалось - оптимальный вариант

    а по хорошему ты прав... надо клиент делать на основе неблокирующих сокетов и
    передавать (размер\ком\сабком\датален\дата)
    но пока пусть будет так
     
  16. X-lord

    X-lord Banned

    Joined:
    16 Dec 2006
    Messages:
    27
    Likes Received:
    4
    Reputations:
    1
    оцени код по 10-и бальной шкале криворукости кодера
     
    1 person likes this.
  17. aivus

    aivus New Member

    Joined:
    25 Dec 2006
    Messages:
    17
    Likes Received:
    4
    Reputations:
    0
    Хай!
    1. Как лучше(и правильней) отделить заголовок от данных полученых с веб-сервера?
    2. Как лучше получать данные с веб-сервера, что бы не ждать, пока по таймауту recv вернет false?
    Code:
    		/*--------Эту херню нада заменить нах-------*/
    		do 
    
    		if (recv(inet_Sock,Buff,4096,0)){
    
    			//MessageBox(0,Buff,"Recv",0);
    			
    		}else break;
    
    		while (1);
    		/*------------------------------------------*/
     
  18. da_ff

    da_ff Elder - Старейшина

    Joined:
    11 Jul 2006
    Messages:
    118
    Likes Received:
    22
    Reputations:
    26
    2 aivus
    1)последовательность "\r\n\r\n" ты б хоть ознакомился с протоколом прежде чем что нибудь писать
    2)используй асинхронные сокеты
     
  19. aivus

    aivus New Member

    Joined:
    25 Dec 2006
    Messages:
    17
    Likes Received:
    4
    Reputations:
    0
    1)Я как раз думал написать в предыдущем посте "кроме \r\n\r\n". Просто думал мож можно как-то иначе, ладно... буду юзать этот способ...
    2)Да тут дело как раз не в том... Просто имхо неправильно ждать таймаута recv и только потом ломать цыкл...
     
  20. VERte][

    VERte][ Elder - Старейшина

    Joined:
    17 May 2007
    Messages:
    240
    Likes Received:
    163
    Reputations:
    32
    Такой вопросец: что делает следущая функция cout.setf(ios::left);
    в учебнике вроде как написано, что сдвигает следущую надпись влево.
    Но когда я записывают код типа:
    cout<<123;
    cout.setf(ios::left);
    cout<<456;
    у меня выводится на экран: 123456
    Может кто подробнее написать, что делает эта функция? (таже в учебнике написано, что по умолчанию стоит cout.setf(ios::right), типа следующая запись выводится справа)
     
Thread Status:
Not open for further replies.