На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
  
    > Помогите... Работа с файлами в сети
      Кто-нибудь знает как отослать\принять файл по сети (TCP/IP) с использованием WinSock.
      Желательно поподробнее
      :-[
        сервак:
        ExpandedWrap disabled
          <br>// server.cpp : Defines the entry point for the application.<br>#include "stdafx.h"<br>#include <ras.h><br>#include <winsock2.h><br>#include <windows.h><br>#include <stdio.h><br>#include <stdlib.h><br>#include <conio.h><br>#include <crtdbg.h><br><br>#define  PORT  28912                                     //порт<br>char* ReceiveFile(char* name,int size,SOCKET s);  //получение файла<br>int scksend(char* data,SOCKET s);                 //посылка сокетом данных <br>int receive(char* buff,int num,SOCKET s);         //прием сокетом данных<br>int parser(char* str);<br>void commands(char** list);<br>SOCKET client;                                       //клиент<br>SOCKET server;                                       //сервер<br>//---------------------------------------------------------------------------<br>//       MAIN (BODY) PROGRAM<br>//---------------------------------------------------------------------------<br>int APIENTRY WinMain(HINSTANCE hInstance,<br>                     HINSTANCE hPrevInstance,<br>                     LPSTR     lpCmdLine,<br>                     int       nCmdShow)<br>{<br>    int i;<br>      bool end;<br>      char getchar[2];<br>      char* argument=(char *)calloc(1024,sizeof(char));<br><br>      //инициализируем процесс библиотеки wsock32.dll<br>      WSADATA WsaData;<br>      int err = WSAStartup (0x0101, &WsaData);<br>      if (err == SOCKET_ERROR)<br>            goto EXIT; <br>      //теперь объявляем переменную типа SOCKET<br>      server = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);<br>      //задаем параметры для сокета (сервера)<br>      if(server==INVALID_SOCKET)<br>            goto EXIT;<br>      SOCKADDR_IN sin;<br>      sin.sin_family = AF_INET;<br>      sin.sin_port = htons(PORT);<br>      sin.sin_addr.s_addr = INADDR_ANY;<br>      //подключаем socket к коммуникационной среде<br>      err = bind( server, (LPSOCKADDR)&sin, sizeof(sin) );<br>      if(err==-1)<br>            goto EXIT;<br>      //создаем очереть для ожедания вызовов от клиентов<br>      err = listen( server, SOMAXCONN);<br>      if(err==-1)<br>            goto EXIT;<br><br>      //вечный цикл для многократного обслушивания запросов от клиентов<br>      while(true)      {<br>            //принемаем запрос от программ-клиента на установление связи<br>            SOCKADDR_IN from;<br>            int fromlen=sizeof(from);<br>            client = accept(server,(struct sockaddr*)&from, &fromlen);<br>            <br>            while(true)      {<br>                  argument[0]= '\0';<br>                  getchar[0] = '\0';<br>                  <br>                  end=false,i=0;<br><br>                  while(!end||i>50) {<br>                        receive(getchar,1,client);<br>                        getchar[0]=*getchar;<br>                        if(getchar[0]=='\0')<br>                              goto EXIT;<br>                        if(getchar[0]!='\n') {<br>                              argument[i]=getchar[0];<br>                              i++;<br>                        }<br>                        else<br>                              end=true;<br>                  }<br>                  argument[i]='\0';<br>                  if(!parser(argument)) //вход в разбор полученной команды <br>                        goto EXIT;<br>            }<br>      }<br><br>EXIT:<br>      free(argument);<br>      if (client!=INVALID_SOCKET)                      // Если клиент еще не слетел, то<br>    closesocket(client);                           // аккурат закрываем<br>      closesocket(server);                             // close server socket <br>  WSACleanup();                                    // free winsock<br>      return 0;<br>}<br>//---------------------------------------------------------------------------<br>//       Функция отсылки данных клиенту<br>//---------------------------------------------------------------------------<br>int scksend(char* data,SOCKET s)<br>{                                        // data - строка для отправки<br>  int  sendchar,                         // Количество отправленных символов<br>       currchar=0,                       // Точка останова отправки<br>       ndata;                            // Длина того, что отправляем<br>  ndata=strlen(data);<br>  while(currchar<ndata) {<br>    sendchar=send(s,(char*)(data + currchar),ndata-currchar,NULL);<br>    if(sendchar==SOCKET_ERROR)<br>      return 0;<br>    currchar+=sendchar;<br>  }<br>  return 1;<br>};<br>//---------------------------------------------------------------------------<br>//       Функция получения данных от клиента<br>//---------------------------------------------------------------------------<br>int receive(char* buff,int num,SOCKET s)       // массив куда получить и кол-во сколько<br>{                                              // надо получить от сервера<br>  int  recvchar;                               // Длина того, что получили<br>  recvchar=recv(client,buff,num,NULL);<br>  if (recvchar==SOCKET_ERROR)<br>        return 0;//goto EXIT;// SERROR();<br>  buff[recvchar]='\0';<br>  return recvchar;<br>};<br>//---------------------------------------------------------------------------<br>//       Функция разбиения строки на команды<br>//---------------------------------------------------------------------------<br>int parser(char* str)<br>{<br>      int j,st=0,count=0;bool sp=true;;<br>      char **s=(char **)calloc(3,sizeof(char*));<br><br>      for(j=0;j<3;j++)<br>            s[j]=(char *)calloc(1024,sizeof(char));<br><br>      for(int i=0;i<strlen(str);i++){<br>            if (str[i] == '$'){<br>                  if (!sp){<br>                        count=0;<br>                        st++;<br>                  }<br>                  sp = true;<br>            }<br>            else{<br>                  sp = false;<br>                  s[st][count]=str[i];<br>                  count++;<br>            }<br>      }<br>      commands(s);                       //выполнение соответсвующей команды<br>      for(j=0;j<Number;j++){<br>            s[j]='\0';<br>            delete[]s[j];<br>      }<br>      return 0;<br>}<br>//---------------------------------------------------------------------------<br>//       Функция выбора команды и выполнение ее<br>//---------------------------------------------------------------------------<br>void commands(char** list)<br>{<br>      if(strcmp(list[0],"FILE")==0)<br>            scksend(ReceiveFile(list[1],atoi(list[2]),client),client);<br><br>}<br>//---------------------------------------------------------------------------<br>//       Подпрограмммы получения файла<br>//---------------------------------------------------------------------------<br>char* ReceiveFile(char* name,int size,SOCKET s)<br>{<br>      int nTotalBytes=0,nDifferentBytes=0; unsigned long nBytesWrite;<br>      bool end=false;      <br>      char* buffer=(char*)calloc(1025,sizeof(char));<br><br><br>      char path[256];<br><br>      sprintf(path,"c:\\\%s",name);<br><br>      HANDLE hFile=CreateFile(path,GENERIC_WRITE,NULL,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);<br>      <br>      if(hFile==INVALID_HANDLE_VALUE)<br>            return "Can't create file";<br>      while( size>nTotalBytes) {<br>            if(size-nTotalBytes>1024)<br>                  nDifferentBytes=1024;<br>            else if(size-nTotalBytes<1024 && size-nTotalBytes>0)<br>                  nDifferentBytes=size-nTotalBytes;<br>            int  recvchar;<br>            recvchar=recv(client,buffer,nDifferentBytes,NULL);<br>            buffer[recvchar]='\0';<br><br>            if(!WriteFile(hFile,buffer,recvchar,&nBytesWrite,NULL))<br>                  return "Can't write to file";<br>            nTotalBytes+=nBytesWrite;<br>      }<br>      CloseHandle(hFile);<br>      free(buffer);<br><br>      if(nTotalBytes==size)<br>            return "File normal received";<br>      else if(nTotalBytes>size)<br>            return "In file write garbage";<br>      return "File not received";<br>}<br>


        клиент:
        ExpandedWrap disabled
          <br>// clientdos.cpp : Defines the entry point for the console application.<br>#include "stdafx.h"<br>#include <winsock2.h><br>#include <windows.h><br>#include <stdio.h><br>#include <stdio.h><br>#include <iostream.h><br>#include <conio.h><br><br>void SEND(char *data,int len,SOCKET s);<br>void SendFile(SOCKET s);<br>void SendMail(SOCKET s);<br>//---------------------------------------------------------------------------<br>//       MAIN (BODY) PROGRAM<br>//---------------------------------------------------------------------------<br>int main(int argc, char* argv[])<br>{<br>      char* address=new char[1024];<br>      char* cmd=new char[2];<br>      printf("Please enter adress as 127.0.0.1\n");<br>      gets(address);<br><br>      //инициализируем процесс библиотеки wsock32.dll<br>  WSADATA WsaData;<br>  WSAStartup (257, &WsaData);<br><br>  //теперь объявляем переменную типа SOCKET<br>  SOCKET s = socket(AF_INET,SOCK_STREAM,IPPROTO_IP);<br>      SOCKADDR_IN sin;<br>  ZeroMemory(&sin, sizeof(sin));                     // Зачистка<br>  sin.sin_family = AF_INET;                          // Тип соединения<br>  sin.sin_port = htons(28912);                       // Порт<br>  sin.sin_addr.s_addr =inet_addr(address);           // IP адрес <br>      <br>  if(connect(s, (PSOCKADDR)&sin, sizeof(SOCKADDR))==-1){<br>        printf("fail connect to server\n");<br>        goto EXIT;<br>  }<br>      printf("connect to server ok\n");<br><br>      <br>BEGIN:<br><br>      printf("1 - for send file,0 - for EXIT\n");<br>      gets(cmd);<br>      switch(atoi(cmd)){<br>            case 0:<br>                  goto EXIT;<br>                  break;<br>            case 1:<br>                  SendFile(s);<br>                  break;<br>      }<br>      char str[256];<br>      int  a;                               <br>    a=recv(s,str,sizeof(str),NULL);<br>      str[a]='\0';<br>      printf("\n\%s\n",str);<br>      goto BEGIN;<br><br>EXIT:<br>      free(address);free(cmd);<br>      if (s!=INVALID_SOCKET)                           // Если клиент еще не слетел, то<br>    closesocket(s);                                // аккурат закрываем<br>  WSACleanup();                                    // free winsock<br>      return 0;<br>}<br>//---------------------------------------------------------------------------<br>//       Функция отсылки данных клиенту<br>//---------------------------------------------------------------------------<br>void SEND(char *data,int len,SOCKET s)<br>{      <br>      int  a,                                // Количество отправленных символов<br>       b=0,                              // Точка останова отправки<br>       ndata;                            // Длина того, что отправляем<br>  ndata=len;<br>  while(b<ndata) {<br>    a=send(s,(char*)(data + b),ndata-b,NULL);<br>    b+=a;<br>  }<br>}<br>//---------------------------------------------------------------------------<br>//       Подпрограмммы посылки файла<br>//---------------------------------------------------------------------------<br>void SendFile(SOCKET s)<br>{<br>      char* fullname=new char[1024];<br>      char* name=new char[1024];<br>      name[0]='\0';<br>      <br>      printf("ENTER FULL PATH\n");<br>      gets(fullname);<br><br>      int Total=0, bResult=1;<br>  unsigned long int nBytesRead=1;<br>  char * inBuffer=new char[1025];<br><br>  HANDLE hFile=CreateFile(fullname,              //name<br>                          GENERIC_READ,          //property<br>                          NULL,<br>                          NULL,<br>                          OPEN_EXISTING,         //how open?<br>                          FILE_ATTRIBUTE_NORMAL, //attr<br>                          NULL);                 //template<br>      if(hFile==INVALID_HANDLE_VALUE){<br>            printf("Error open file");<br>            exit(0);<br>      }<br><br>  int Size=GetFileSize(hFile,NULL);<br>      char* size=new char[1024];<br>      itoa(Size,size,10);<br><br>      strrev(fullname);<br>      for(int i=0;fullname[i]!='\\';i++)<br>            name[i]=fullname[i];<br>      name[i]='\0';<br>      strrev(name);<br><br>  send(s,"FILE$",strlen("FILE$"),NULL);<br>      send(s,name,strlen(name),NULL);<br>      send(s,"$",1,NULL);<br>      send(s,size,strlen(size),NULL);<br>      send(s,"\n",1,NULL);<br><br>  while(bResult && nBytesRead != 0){              //While not eof.......<br>   bResult = ReadFile(hFile,inBuffer,1024,&nBytesRead, NULL);<br><br>   if(bResult && nBytesRead!=0 ){<br>             Total+=nBytesRead;                           //Send buf and his size<br>             SEND(inBuffer,nBytesRead,s);<br>             printf(".");<br>   }<br>      }<br>      CloseHandle(hFile);                  <br>}<br>


        а теперя принцип работы (это я вырезал кусок с проги когда-то писал чтото типа RAdmin) - сервак получает команду FILE$ИМЯ_ФАЙЛА$РАЗМЕР_ФАЙЛА\n, концом каждой команды является символ \n. Затем команда разбирается на куски отделяемые $.
        Затем все это передается в соответсвующую подрограмму с соответсвующими аргументами. В принципе можно самому задавать свои прототипы команд - главное шобы на серваке был их разбор и выполнение.

        з.ы. вышеприведенный код можно запихать в класс, почистить/улучшить - все на усмотрение. Это ОЧЕНЬ простой пример - хдесь нет ни проверок на ошибок - вообще ничего практически нету - так что это только сам принцип (по крайней мере как это понимаю я). Так что ясен пень этот код никакой критике не выдержит ;D
          Огромное спасибо  ;D
          0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
          0 пользователей:


          Рейтинг@Mail.ru
          [ Script execution time: 0,0515 ]   [ 16 queries used ]   [ Generated: 13.12.24, 00:32 GMT ]