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

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

Вернуться   Форум программистов > IT форум > Помощь студентам
Регистрация

Восстановить пароль

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

Ответ
 
Опции темы Поиск в этой теме
Старый 08.01.2013, 18:58   #1
Freedo
Пользователь
 
Регистрация: 16.10.2012
Сообщений: 27
По умолчанию Доработка TCP чата в Visual C++

Здравствуйте, требуется небольшая помошь. Есть клиент и сервер написанные в Visual C++. Эти приложения работают по протоколу TCP.

После подключения клиента к серверу, сервер отправляет клиенту приветственное сообщение, затем клиент имеет возможность посылать сообщения серверу, и ждёт от него это письмо обратно (это сделано для того, в случае если сервер стал недоступен у клиента будет ошибка, то есть что-бы убедиться в том что сервер работает.) После того, как ответ пришёл, клиент может набирать новое сообщение. На самом сервере ни каких сообщений не выводится.

Собственно, что мне нужно. Нужно чтобы сервер выводил на экран принятые сообщения, а клиент не выводил на экран присланные ему подтверждения. Задание простое, но у меня косячно выходит реализовать это. Если кто хочет сделать за небольшую плату, то я согласен.
Freedo вне форума Ответить с цитированием
Старый 08.01.2013, 18:58   #2
Freedo
Пользователь
 
Регистрация: 16.10.2012
Сообщений: 27
По умолчанию

Код:
// TCP сервер
#pragma comment ( lib, "ws2_32.lib" )
#include <stdio.h>
#include <winsock2.h>


// Выводит на экран количество активных пользователей
#define PRINTNUSERS if (nclients) printf("%d user online\n", nclients); \
        else printf("No User online\n");

// прототип функции, обслуживающий подключившихся пользователей
DWORD WINAPI SexToClient(LPVOID client_socket);

int nclients = 0;                                          // Изначальное колличество клиентов
int main()
{
    char buff[1024]; // Буфер для различных нужд
    printf("TCP Server Started\n");

	// Инициализация WinSock
	WORD wVersionRequested = MAKEWORD (2,2);                // Версия библиотеки
	WSADATA wsaData;
    int err = WSAStartup(wVersionRequested, &wsaData);
	if (err !=0)                                             // Если не равно 0
    {
      printf("WSAStartup error: %d\n",WSAGetLastError());    // Номер ошибки
    }
	else printf("WinSock initialized\n");                    // Инициализация прошла успешно

    // Открытие и закрытие сокета
    SOCKET mysocket = socket(AF_INET,SOCK_STREAM,0);           // Протокол IPv4, TCP
    if (mysocket==INVALID_SOCKET)                             // Если функция завершилась неудачно
    {
      printf("Socket error: %d\n",WSAGetLastError());
      WSACleanup();                                          // Завершение работы с WinSock
    }

	// Связывание сокета 
    sockaddr_in local_addr;                                                  // Заполнени структуры
    local_addr.sin_family=AF_INET;                                           // Семейство адресов IPv4
    local_addr.sin_addr.s_addr=htonl(INADDR_ANY);                            // Все адреса локального компьютера
    local_addr.sin_port=htons(5150);                                         // Номер порта 5150
	                                                                  // Привязка сокета к сетевому адресу
    if (bind(mysocket,(sockaddr *) &local_addr, sizeof(local_addr))==SOCKET_ERROR)   // Если функция завершилась неудачно 
    {
      printf("bind error: %d\n",WSAGetLastError());                   // Вывод сообщения и номера ошибки
      closesocket(mysocket);                                           // Завершение работы с сокетом
    }

	// Ожидание подключений
    if (listen(mysocket, 5))
    {
        printf("Error listen %d\n", WSAGetLastError());
        closesocket(mysocket);
        WSACleanup();
    }
    printf("Waiting for connection...\n");



    //Извлечение сообщение из очереди
    SOCKET client_socket; // сокет для клиента
    sockaddr_in client_addr; // адрес клиента (заполняется системой)
    // функции accept необходимо передать размер структуры
    int client_addr_size = sizeof(client_addr);
    // цикл извлечения запросов на подключение из очереди
    while ((client_socket = accept(mysocket, (sockaddr *)&client_addr, \
           &client_addr_size)))
    {
        nclients++; // увеличиваем счетчик подключившихся клиентов
        // пытаемся получить имя хоста
        HOSTENT *hst;
        hst = gethostbyaddr((char *)&client_addr. sin_addr.s_addr, 4, AF_INET);
        // вывод сведений о клиенте
        printf("+%s [%s] new connect!\n",
        (hst) ? hst->h_name : "", inet_ntoa(client_addr.sin_addr));
        PRINTNUSERS
        // Вызов нового потока для обслужвания клиента
        // Да, для этого рекомендуется использовать _beginthreadex
        // но, поскольку никаких вызовов функций стандартной Си библиотеки
        // поток не делает, можно обойтись и CreateThread
        DWORD thID;
        CreateThread(NULL, NULL, SexToClient, &client_socket, NULL, &thID);
    }
    return 0;
}
// Эта функция создается в отдельном потоке
// и обсуживает очередного подключившегося клиента независимо от остальных
DWORD WINAPI SexToClient(LPVOID client_socket)
{
    SOCKET my_sock;
    my_sock = ((SOCKET *)client_socket)[0];
    char buff[20 * 1024];
    #define sHELLO "Connection establishment\r\n"
    // отправляем клиенту приветствие
    send(my_sock, sHELLO, sizeof(sHELLO), 0);
    // цикл эхо-сервера: прием строки от клиента и возвращение ее клиенту
    int bytes_recv;
    while ((bytes_recv = recv(my_sock, &buff[0], sizeof(buff), 0)) &&
    bytes_recv != SOCKET_ERROR)
    send(my_sock, &buff[0], bytes_recv, 0);
    // если мы здесь, то произошел выход из цикла по причине
    // возращения функцией recv ошибки - соединение с клиентом разорвано
    nclients--; // уменьшаем счетчик активных клиентов
    printf("-disconnect\n"); PRINTNUSERS
    // закрываем сокет
    closesocket(my_sock);
    return 0;
}
Freedo вне форума Ответить с цитированием
Старый 08.01.2013, 18:59   #3
Freedo
Пользователь
 
Регистрация: 16.10.2012
Сообщений: 27
По умолчанию

Код:
// TCP клиент
#pragma comment ( lib, "ws2_32.lib" )

  #include <stdio.h>
  #include <winsock2.h>

  #define SERVERADDR "127.0.0.1"

  int main()
  {
    char buff[1024];

    printf("TCP Client Started\n");

	// Инициализация WinSock
	WORD wVersionRequested = MAKEWORD (2,2);
	WSADATA wsaData;
    int err = WSAStartup(wVersionRequested, &wsaData);
	if (err !=0) 
    {
      printf("WSAStartup error: %d\n",WSAGetLastError());
    }

    // Открытие и закрытие сокета
    SOCKET my_sock=socket(AF_INET, SOCK_STREAM, 0);
    if (my_sock==INVALID_SOCKET)
    {
      printf("socket() error: %d\n",WSAGetLastError());
      WSACleanup();
    } 

    // Связывание сокета
    sockaddr_in dest_addr;                           // заполнение структуры sockaddr_in
    dest_addr.sin_family=AF_INET;                    // указание адреса и порта сервера
    dest_addr.sin_port=htons(5150);
    dest_addr.sin_addr.s_addr=inet_addr(SERVERADDR);

    // адрес сервера получен – пытаемся установить
    // соединение 
    if (connect(my_sock,(sockaddr *)&dest_addr, sizeof(dest_addr)))
    {
      printf("Connect error %d\n",WSAGetLastError());
    }

	printf("Connecting with "SERVERADDR" \n");
    int nsize;
        while((nsize=recv(my_sock,&buff[0],sizeof(buff)-1,0))!=SOCKET_ERROR)

	{
      buff[nsize]=0;

      // выводим на экран 
      printf("S=>C:%s",buff);

      // читаем пользовательский ввод с клавиатуры
      printf("S<=C:"); fgets(&buff[0],sizeof(buff)-1,stdin);

      // передаем строку клиента серверу
      send(my_sock,&buff[0],sizeof(buff)-1,0);
    }
    printf("Recv error %d\n",WSAGetLastError());
    closesocket(my_sock);
    WSACleanup();
  }
Freedo вне форума Ответить с цитированием
Ответ


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



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Доработка multiple-mouse приложения Visual Studio2010 C# escaflowne Фриланс 0 20.02.2012 04:49
Не получается принять TCP/IP пакет более 2048 байт. Visual C++ Gvaler C/C++ Сетевое программирование 3 28.09.2011 23:00
Исходники TCP (Winsock) чата на C++ с GUI MrRockchip Visual C++ 0 25.02.2011 22:20
как создать TCP клиент, TCP сервер ? DreamMaster911 C/C++ Сетевое программирование 1 26.10.2010 15:05
Требуется приложение на Visual Studio, TCP IP протокол. borman487 Фриланс 8 01.06.2010 19:52