Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > C/C++ Сетевое программирование
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 24.07.2010, 01:16   #1
n3sh
Пользователь
 
Регистрация: 24.07.2010
Сообщений: 25
По умолчанию Winsock

Всем привет.Начал разбиратся с сокетами и сразуже появились проблемы отправки и получения данных.С сервера на клиент погу отправить текст,а вот с клиента на сервер нет и если отправляю с сервера на клиент то на клиенте выводится текст только до первого пробела.И еще как отправить какую нибудь системную команду например ping.В чем проблема?

Сервер:
Код:
#include <stdio.h>
#include <iostream>
#include <winsock2.h>
#pragma comment( lib, "wsock32.lib" )
#define sHello "-------------------------------------Hello--------------------------------------"
using namespace std;
int main(int argc, char* argv[])
{
        printf("                             TCP Server by Nesh\n\n\n");
char buff[1024];
char response[1024] = {0};
sockaddr_in s_a;
WSADATA wd;
int client_number = 0;
 
WSAStartup( MAKEWORD( 2, 2 ), &wd );
 
SOCKET s = socket( AF_INET, SOCK_STREAM, 0 );
if (s == INVALID_SOCKET) return 255;
 
s_a.sin_addr.s_addr = inet_addr( "127.0.0.1" );
s_a.sin_port = htons( 666 );
s_a.sin_family = AF_INET;
 
if(bind(s,(sockaddr *)&s_a,sizeof(s_a)) == SOCKET_ERROR) {
        cout << "Bind error" << endl;
        return 0;
}
if(listen(s,0x3) == SOCKET_ERROR) {
        cout << "Listen error" << endl;
        return 0;
}
printf("Waiting connection...\n");
sockaddr_in client_addr;
int client_addr_size = sizeof(client_addr);
SOCKET client_socket;
 
 
while(client_socket = accept(s,(sockaddr *)&client_addr,&client_addr_size)) {
         if(client_socket == SOCKET_ERROR) {
                 printf("--------------SOCKET ERROR-----------");                
                 break;}
         client_number++;
        
        HOSTENT *hst;
        hst=gethostbyaddr((char *) &client_addr.sin_addr.s_addr,4,AF_INET);
        printf("+%s [%s] new connect,client number is %d !\n",(hst)?hst->h_name:"",inet_ntoa(client_addr.sin_addr),client_number);
 
         int data_send = send(client_socket,sHello,strlen(sHello),0);
         if(data_send == SOCKET_ERROR) {
                 printf("Error send");
                 break;
         } else if (data_send == 0) {
         printf("connection closed");
             break;
         }
      int data_recv = recv(client_socket,response,strlen(response),0);
          if(data_recv == SOCKET_ERROR) {
                  printf("Recv error");
                  break;
          }
          printf("%s",response);
}
closesocket( s ); 
WSACleanup();
system("pause");
return 0;
}
Клиент:
Код:
#include <stdio.h>
#include <iostream>
#include <winsock2.h>
#pragma comment( lib, "wsock32.lib" )
using namespace std;
int main(int argc, char* argv[])
{
sockaddr_in dest_addr;
WSADATA wd;
char response[1024] = {0};
char buff[1024];
WSAStartup( MAKEWORD( 2, 2 ), &wd );
 
SOCKET s = socket( AF_INET, SOCK_STREAM, 0 );
if (s == INVALID_SOCKET) return 255;
 
dest_addr.sin_addr.s_addr = inet_addr( "127.0.0.1" );
dest_addr.sin_port = htons( 666 );
dest_addr.sin_family = AF_INET;
 
 
    if(connect( s, (struct sockaddr*)&dest_addr, sizeof( dest_addr ) ) == SOCKET_ERROR) {
     printf("                              Connection error\n");
         system("PAUSE"); 
         return 0;
}
 
        while(1) {
  int data_recv = recv(s,response,sizeof(response),0);
     if(data_recv == SOCKET_ERROR) {
           printf("Recv ERROR");
          break;
 
} else if (data_recv == 0) {
        printf("connection closed");
       break;
         }
          printf("%s\n",response);
 
          cin >> buff;
          int data_send = send(s,buff,strlen(buff),0);
          if(data_send == SOCKET_ERROR){
                  printf("Send error");
                  break;
          }}
 
closesocket( s ); 
WSACleanup();
system("pause");
return 0;
}
n3sh вне форума Ответить с цитированием
Старый 24.07.2010, 16:55   #2
pu4koff
Старожил
 
Аватар для pu4koff
 
Регистрация: 22.05.2007
Сообщений: 9,065
По умолчанию

Особо не вникал в код, но в нем распространенная ошибка уже есть.
Используется протокол TCP. Это потоковый протокол и как поток данных будет разбит при передаче/приемке неизвестно. Нельзя с уверенностью сказать, что сообщение уйдёт за раз. send может отправить только кусок сообщения, а может и целиком, зависит это от многих факторов. Та же ситуация и с функцией recv. Она может получить только часть сообщения, а не всё целиком.
Правильнее отправлять сообщение в цикле, с проверкой, что отправлено всё сообщение. Если функция send отправила 20 байт из 30, значит нужно вызвать еще раз send для оставшихся 10 байт, из которых отправиться на клиента может только 5. И так по кусочкам отправится всё сообщение и так же из кусочков нужно будет его собирать на клиенте.
Чтобы отправить результат работы системной функции, то здесь есть 2 варианта:
1) вызывать не ping ya.ru, a ping ya.ru > temp.txt и в итоге в файле temp.txt получим результат работы функции.
2) Перенаправить поток вывода для функции в память, но как это делается я не подскажу, т.к. не помню. Склероз См. в яндексе про перенаправление stdout.
И сервер какой-то странный. Самый простой вариант реализации (на мой взгляд): В функции main ждем подключения нового клиента. Пришел клиент - создаем для него отдельный поток (_beginthread или CreateThread или ...), в который передаем сокет для обмена данными с этим клиентом. В потоке уже будут выполняться все эти send/recv для конкретного клиента. Если всё это делать без потоков на каждого клиента, то много проблем всплывет.

Последний раз редактировалось pu4koff; 24.07.2010 в 16:59.
pu4koff вне форума Ответить с цитированием
Старый 25.07.2010, 17:55   #3
n3sh
Пользователь
 
Регистрация: 24.07.2010
Сообщений: 25
По умолчанию

pu4koff,можно пример пожалуйста?

Последний раз редактировалось n3sh; 26.07.2010 в 04:41.
n3sh вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
WinSock ImmortalAlexSan Работа с сетью в Delphi 7 06.06.2010 22:41
WinSock ImmortalAlexSan Работа с сетью в Delphi 1 11.05.2010 14:42
WinSock profi Win Api 8 11.01.2010 21:13
WinSock Killbrum Win Api 1 18.10.2009 15:15
Proxy в WinSock SHEI'TI Работа с сетью в Delphi 3 29.03.2008 18:27