Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[18.97.14.86] |
|
Сообщ.
#1
,
|
|
|
Кто-нибудь знает как отослать\принять файл по сети (TCP/IP) с использованием WinSock.
Желательно поподробнее :-[ |
Сообщ.
#2
,
|
|
|
сервак:
<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> клиент: <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 |
Сообщ.
#3
,
|
|
|
Огромное спасибо ;D
|