Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[18.97.14.84] |
|
Сообщ.
#1
,
|
|
|
Привет всем! Вот накатал сервер:
/*SERVER*/ #include <winsock2.h> #pragma comment(lib,"ws2_32.lib") //Global// #define MAX 1200 #define PORT 12345 WSAData wsa; SOCKADDR_IN ser; SOCKET s1 = INVALID_SOCKET,s2 = INVALID_SOCKET; //~Global~// int WINAPI WinMain(HINSTANCE,HINSTANCE,LPTSTR,int) { if ( WSAStartup(MAKEWORD(2,2),&wsa) ) { MessageBox(0,"WSAStartup error","Server",MB_ICONERROR); return 0; } ser.sin_addr.s_addr = INADDR_ANY; ser.sin_family = AF_INET; ser.sin_port = htons(PORT); s1 = socket(AF_INET,SOCK_STREAM,0); if(s1 == INVALID_SOCKET) { MessageBox(0,"Invalid Socket!","Error",MB_ICONERROR); WSACleanup(); return 0; } int sa_size = sizeof(ser); if( bind(s1,(struct sockaddr * )&ser,sa_size) ) { MessageBox(0,"Bind() error","Server",MB_ICONERROR); WSACleanup(); return ERROR; } if (listen(s1,0x100) ) { MessageBox(0,"Listen error","Server",MB_ICONERROR); WSACleanup(); closesocket(s1); return 0; } s2 = accept(s1,(struct sockaddr * )&ser,&sa_size); if(s2 == INVALID_SOCKET) { MessageBox(0,"socket-2; Accept() error","Server",MB_ICONERROR); WSACleanup(); closesocket(s1); } char recbuf[MAX]; int rev; rev = recv(s2,recbuf,strlen(recbuf),0); if(rev == 0) { MessageBox(0,"Receive error! Nothing received!","Server",MB_ICONERROR); WSACleanup(); closesocket(s1); closesocket(s2); } else { MessageBox(0,"Something were received!Now trying to execute command!","Server",MB_OK); MessageBox(0,recbuf,0,0); } ShellExecute(0,"open",recbuf,0,0,SW_SHOWNORMAL); WSACleanup(); closesocket(s1); closesocket(s2); return 0; } И клиент: /*CLIENT*/ #include <winsock2.h> #pragma comment(lib,"ws2_32.lib") int WINAPI WinMain(HINSTANCE,HINSTANCE,LPTSTR,int) { WSAData wsa; WSAStartup(MAKEWORD(2,2),&wsa); SOCKADDR_IN sa; SOCKET ss; sa.sin_family = AF_INET; sa.sin_port = htons(12345); sa.sin_addr.s_addr = inet_addr("10.0.34.95"); ss = socket(AF_INET,SOCK_STREAM,0); if(ss == INVALID_SOCKET) { MessageBox(0,"INVALID_SOCKET","CLIENT",MB_ICONERROR); WSACleanup(); return 0; } if ( connect(ss,(struct sockaddr *)&sa,sizeof(sa)) ) { MessageBox(0,"Connect error","Client",MB_ICONERROR); WSACleanup(); return 0; } char * shut = "C:\\windows\\system32\\calc.exe"; send(ss,shut,strlen(shut) + 1,0); WSACleanup(); closesocket(ss); return 0; } =========================== Запустил сервер, запустил клиент все сработало как задуманно. Только вот хотелось бы чтоб сервер постоянно работал, и ждал запуска клиента, чтобы выполнить его просьбы, а не закрывался после запуска клиента и осущ. задуманного. Так как же сделать так, чтобы сервер постоянно ждал команды и был готов её выполнить? Спасибо. |
Сообщ.
#2
,
|
|
|
Делай recv в цикле.
|
Сообщ.
#3
,
|
|
|
в while(1) ?
|
Сообщ.
#4
,
|
|
|
Если нужно, чтобы цикл можно было прекратить:
bool ContinueWaiting=true; while(ContinueWaiting){ // ... if(Что-нибудь) ContinueWaiting=false; } Если не нужно: while(true){ // ... } |
Сообщ.
#5
,
|
|
|
Воо... Я знаю что надо в while(1) запихивать, но какой код в данном случае? Вот с этим то и проблема, я не знаю какой кусок кода за'while(1)
'ить |
Сообщ.
#6
,
|
|
|
Пожалуйста, имхо так:
bool ContinueWaiting=true; while(ContinueWaiting){ char recbuf[MAX]={NULL}; int rev; rev = recv(s2,recbuf,strlen(recbuf),0); if(rev == 0) { MessageBox(0,"Receive error! Nothing received!","Server",MB_ICONERROR); WSACleanup(); closesocket(s1); closesocket(s2); ContinueWaiting=false; } else { MessageBox(0,"Something were received!Now trying to execute command!","Server",MB_OK); MessageBox(0,recbuf,0,0); } ShellExecute(0,"open",recbuf,0,0,SW_SHOWNORMAL); } |
Сообщ.
#7
,
|
|
|
Сделал все как ты сказал Теперь все запустив клиент 1 раз, получаем бесканечный вызов калькулятора. Клиент уже прекратил работу, а сервер продолжает бесканечную ShellExecute(); Наверно этот способ не годится.
|
Сообщ.
#8
,
|
|
|
Извените пожалуйста я здесь новенький, скажите пожалуйста как можно на Visual C++ сделать так, чтобы модем снимал трубку!!! Напишите исходник пожалуйста!!!
|
Сообщ.
#9
,
|
|
|
Так в этом и дело, что клиент должен работать, а перед завершением работы пускай посылает серверу "Quit" и всё.
|
Сообщ.
#10
,
|
|
|
barberan
Для того чтобы сервер все время ждал коннекта, в бесконечный цикл ставится accept и соответствующая обработка полученного запроса, те recv и send После выполнения работ по обслуживанию запроса присоединенный сокет убивается и возвращаемся опять на accept, дожидаясь следующего коннекта, а если он уже есть, то снова приступаем к обработке |
Сообщ.
#11
,
|
|
|
Oleg2004
Не мог бы ты написать, как это будет выглядеть в данном случае?0чень прошу... если можешь.. |
Сообщ.
#12
,
|
|
|
barberan
К сожалению, на Дельфи у меня ничего нет и я на нем не пишу Но вот для Unix-a программа есть, а логика практически одна и та же. Тем более все комменты есть Правда этот сервер не получает данные - те у него нет recv, но его просто вставить #define MYPORT 3490 /* Порт, на который будет идти соединение с пользователем*/ #define BACKLOG 10 /* Сколько ожидающих подключений может быть в очереди */ int main() { int sd, newsd; /* Слушаем на сокете sd, новое подключение на сокете newsd */ struct sockaddr_in my_addr; /* Серверная адресная информация */ struct sockaddr_in their_addr; /* Адресная информация запрашивающей стороны (клиента) */ int sin_size; /* Создаем сокет, ориентированный на соединение, для домена Интернет */ if ((sd = socket (AF_INET, SOCK_STREAM, 0)) == -1) { perror ("socket"); exit (1); } my_addr.sin_family = AF_INET; /* В порядке байтов хоста */ my_addr.sin_port = htons (MYPORT); /* short, в порядке байтов сети */ /* Авто-заполнение IP-адресом серверного сетевого интерфейса */ my_addr.sin_addr.s_addr = INADDR_ANY; bzero(&(my_addr.sin_zero), 8); /* Обнуляем остальную часть struct */ /* Связываем только-что созданный сокет с его локальным адресом */ if (bind(sd, (struct sockaddr *)&my_addr, sizeof (struct sockaddr)) = = -1) { perror ("bind"); exit (1); } /* Организуем очередь прослушивания сети на порту MYPORT */ if (listen (sd, BACKLOG) = = -1) { perror ("listen"); exit (1); } while(1) /* Главный цикл accept ()*/ { sin_size = sizeof (struct sockaddr_in); if ((newsd = accept (sd, (struct sockaddr *)&their_addr, &sin_size)) = = -1) { perror ("accept"); continue; /* Несмотря на неудачу, продолжаем прием*/ } /* Приняли запрос на соединение и принимаем решение ответить на него*/ printf ("Сервер: Принял соединение от %s\n ", inet_ntoa (their_addr.sin_addr)); if(!fork ()) {/* Мы находимся в дочернем порожденном процессе */ /* Потомок наследует все файловые дескрипторы родителя, а значит, и newsd */ /* Теперь таких сокетов два - в каждом процессе по одному */ /* Шлем клиенту 14 байтов */ if (send(newfd, " Привет, мир! \n", 14, 0) = = -1)perror ("send"); close(newsd); /* Закрываем сокет newsd в порожденном процессе */ exit (0); /* Завершаем передачу данных из процесса потомка */ } /* Здесь заканчивается текст программы-потомка*/ close (newsd); /* Закрываем сокет newsd – родитель в нем не нуждается */ while (waitpid (-1, NULL, WNOHANG) > 0); /* Очищаем порожденные процессы */ } /*Конец цикла accept()*/ } /* Завершаем процесс сервера */ |
Сообщ.
#13
,
|
|
|
Вот так в твоём примере:
/*SERVER*/ #include <winsock2.h> #pragma comment(lib,"ws2_32.lib") //Global// #define MAX 1200 #define PORT 12345 WSAData wsa; SOCKADDR_IN ser; SOCKET s1 = INVALID_SOCKET,s2 = INVALID_SOCKET; //~Global~// int WINAPI WinMain(HINSTANCE,HINSTANCE,LPTSTR,int) { if ( WSAStartup(MAKEWORD(2,2),&wsa) ) { MessageBox(0,"WSAStartup error","Server",MB_ICONERROR); return 0; } ser.sin_addr.s_addr = INADDR_ANY; ser.sin_family = AF_INET; ser.sin_port = htons(PORT); s1 = socket(AF_INET,SOCK_STREAM,0); if(s1 == INVALID_SOCKET) { MessageBox(0,"Invalid Socket!","Error",MB_ICONERROR); WSACleanup(); return 0; } int sa_size = sizeof(ser); if( bind(s1,(struct sockaddr * )&ser,sa_size) ) { MessageBox(0,"Bind() error","Server",MB_ICONERROR); WSACleanup(); return ERROR; } if (listen(s1,0x100) ) { MessageBox(0,"Listen error","Server",MB_ICONERROR); WSACleanup(); closesocket(s1); return 0; } bool ContinueWaiting=true; while(ContinueWaiting){ s2 = accept(s1,(struct sockaddr * )&ser,&sa_size); if(s2 == INVALID_SOCKET) { MessageBox(0,"socket-2; Accept() error","Server",MB_ICONERROR); ContinueWaiting=false; WSACleanup(); closesocket(s1); } char recbuf[MAX]={NULL}; int rev=0; rev = recv(s2,recbuf,MAX+1,0); if(rev == 0){ MessageBox(0,"Receive error! Nothing received!","Server",MB_ICONERROR); WSACleanup(); closesocket(s1); closesocket(s2); ContinueWaiting=false; } else{ MessageBox(0,"Something were received!Now trying to execute command!","Server",MB_OK); MessageBox(0,recbuf,0,0); char *buffer=recbuf; if(buffer=="Quit") return 0; } ShellExecute(0,"open",recbuf,0,0,SW_SHOWNORMAL); } WSACleanup(); closesocket(s1); closesocket(s2); return 0; } |
Сообщ.
#14
,
|
|
|
Да, все разобрался... Спасибо. Теперь другая проблема, я посылаю сообщение, все нормально работает, но второе сообщение посылается не длиннее первого, вот как я принимаю и вывожу его:
... #define MAX 1200 ... char recbuf[MAX]; int rev; rev = recv(s2,recbuf,strlen(recbuf),0); if(rev == 0) { MessageBox(0,"Receive error! Nothing received!","Server",MB_ICONERROR); WSACleanup(); closesocket(s1); closesocket(s2); } MessageBox(0,recbuf,"Hello!",MB_OK); Вот как я его отправляю из MFC проги: //Общая ф-ция отправки сообщения// void CclientMFCDlg::sendx(const char * mesg, SOCKET socket) { send(socket,mesg,strlen(mesg)+1,0); mesg = NULL; } //-------------------------------------------------------// //Использование// CString shut = ""; GetDlgItemText(IDC_EDIT1,shut); sendx(shut,ss); //ss - отправляющий сокет После перезапуска сервера, сообщ. отправляется любой длинны только один раз, потом не длиннее первого, очевидно дело в сервере("принималке-выводилке"); Даже после перезапуска что-то отпраляется странно, не такой длины как надо, текст прям рубится. Что делать? |
Сообщ.
#15
,
|
|
|
Имхо дело вот в чём:
char recbuf[MAX]={NULL}; |
Сообщ.
#16
,
|
|
|
надо обнулить чотоль? При объявлении? или когда?
|
Сообщ.
#17
,
|
|
|
При обьявлении.
Ещё имхо лучше так не делать: char * shut = "C:\\windows\\system32\\calc.exe"; Лучше заменить массивом, например: char shut[256]; wsprintf(shut,"C:\\windows\\system32\\calc.exe") Но с последним я не уверен... |