Модераторы: feodorv
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Client и Server. Пишем чат. Пишем чат. 
:(
    Опции темы
NURMS
Дата 1.1.2008, 23:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 65
Регистрация: 20.4.2007

Репутация: нет
Всего: нет



Всем привет. У меня есть код для клиента и сервера:

Сервер:

Код

#include <winsock2.h>
#include <iostream.h>

DWORD Client(LPVOID Param)
{
    SOCKET ClientSocket = *(SOCKET *)Param;

    while(true)
    {
        char Buffer[100];
        
        memset((void *)Buffer, 0, 100);

        int asc = recv(ClientSocket, Buffer, 100, 0);

        if(asc < 0)
        {
            return -1;
        }

        cout<<"Client "<<ClientSocket<<": "<<Buffer<<endl;

        cout<<"Write: ";
        cin>>Buffer;
        
        send(ClientSocket, Buffer, strlen(Buffer), 0);
    }

    return 0;
}



int main()
{
  WSADATA Data;
    

   WSAStartup(MAKEWORD(2, 2), &Data);

    SOCKET S = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

    sockaddr_in address;
    address.sin_family = AF_INET;
    address.sin_port = htons(2000);
    address.sin_addr.s_addr = ADDR_ANY;

    bind(S, (sockaddr*)&address, sizeof(address));
    
    listen(S, 0);

    while(true)
    {
        SOCKET ClientSocket = accept(S, 0, 0);
        if(ClientSocket == INVALID_SOCKET)continue;

        сout<<"Incoming connection from client socket: "<<ClientSocket<<endl;

        CreateThread(0, 0, (LPTHREAD_START_ROUTINE)&Client, (LPVOID)&ClientSocket, 0, 0);

    }

    WSACleanup();

    return 0;
}



Клиент:

Код

#include <winsock2.h>
#include <iostream.h>

int main()
{
    WSADATA Data;
    
    WSAStartup(MAKEWORD(2, 2), &Data);

    SOCKET S = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
  
    sockaddr_in address;
    address.sin_family = AF_INET;
    address.sin_port = htons(2000);
    address.sin_addr.s_addr = inet_addr("127.0.0.1");

    while (true)
    {
    if( connect(S, (sockaddr*)&address, sizeof address))
    {
        cout<<"Server Not Found."<<endl;
        //return -1;

        Sleep(1000);
    }
    else
    {
        goto connected;
    }
    }

connected:
    
    while(true)
    {
        char Buffer[100];
        cout<<"Write: ";
        cin>>Buffer;

        send(S, Buffer, strlen(Buffer), 0);

        memset((void *)Buffer, 0, 100);

        recv(S, Buffer, 100, 0);

        cout<<"Server "<<S<<": ";
        cout<<Buffer<<endl;
    }

    WSACleanup();
    return 0;
}



Но он работает так, что клиент отправляет пакет и ждёт ответа, а если убрать recv, то отправленное сервером до него не дойдёт. Короче нужно чтобы:

1. Отправка и получение пакетов была бы независимой. Т.е. точно так как в этих чатах. В любой момент отправлять и получать.
2. Всех клиентов надо где-то хранить, чтобы могли осуществить например такое: некоторый клиент отправляет некоторое сообщение серверу, а тот уже отправляет всем остальным клиентам.

И ещё вопрос. Где у Visual C++ 7.0 добавлять библиотеки *.lib. В шестом понятно, а здесь убрали.
PM MAIL   Вверх
bsa
Дата 2.1.2008, 00:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: нет
Всего: 196



думаю, тебе поможет функция ioctlsocket() (флаг FIONREAD)
PM   Вверх
Kill_em_all
Дата 9.1.2008, 22:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 52
Регистрация: 2.4.2005

Репутация: нет
Всего: нет



Цитата

И ещё вопрос. Где у Visual C++ 7.0 добавлять библиотеки *.lib. В шестом понятно, а здесь убрали. 



Впиши в код
#pragma comment(lib, "ws2_32.lib")



PM MAIL   Вверх
NURMS
Дата 11.1.2008, 22:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 65
Регистрация: 20.4.2007

Репутация: нет
Всего: нет



Так. Одно сделал. Всего лишь надо было отправку у клиента сделать отделным потоком. Но теперь остаётся второе. Сейчас когда клиент подключается, то его порт вводится в массив. Но не могу отследить закрытие клиентского окна, чтобы убрать данный порт из массива. Упс. Тут ещё хуже проблема. Сервер в себе держит сокет закрытого клиента. Т.е когда я создал два... А, чёрт понятно. У меня тут ClientSend не закрывается. Но я в него не могу засунуть recv, тогда он будет либо ожидать получения, либо отправку. И закроется, если я отправлю пакет закрывшемуся клиенту. Вот блин. Значит надо ещё у ClientReceive в if(asc < 0) закрыть поток ClientSend. Так у нас есть ExitThread но что-то не то. Что же делать? smile 

Сервер:

Код

#include <winsock2.h>
#include <iostream.h>

int Clients[10];

DWORD ClientReceive(LPVOID Param)
{
    SOCKET ClientSocket = *(SOCKET *)Param;

    while(true)
    {
        char BufferReceive[100];
        
        memset((void *)BufferReceive, 0, 100);

        //////////////////////////////////////////////////////////////////////////

        int asc = recv(ClientSocket, BufferReceive, 100, 0);

        if(asc < 0)
        {
            

            return -1;
        }

        cout<<"Client "<<ClientSocket<<": "<<BufferReceive<<endl;

        ////////////////////////////////////////////////////////////////////////////
    }

    return 0;
}

DWORD ClientSend(LPVOID Param)
{
    SOCKET ClientSocket = *(SOCKET *)Param;

    char Connected[] = "::: Server On Line ::::";

    send(ClientSocket, Connected, strlen(Connected), 0);

    while(true)
    {
        char BufferSend[100];

        cout<<" Letter to "<<ClientSocket<<" :";

        memset((void *)BufferSend, 0, 100);

        cin>>BufferSend;
       
        send(ClientSocket, BufferSend, strlen(BufferSend), 0);
        
        
    }

    return 0;
}



int main()
{
    WSADATA Data;
    

    WSAStartup(MAKEWORD(2, 2), &Data);

    SOCKET S = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

    sockaddr_in address;
    address.sin_family = AF_INET;
    address.sin_port = htons(2000);
    address.sin_addr.s_addr = ADDR_ANY;

    bind(S, (sockaddr*)&address, sizeof(address));
    
    listen(S, 0);

    memset((void *)Clients, 0, 10);

    while(true)
    {
        SOCKET ClientSocket = accept(S, 0, 0);
        if(ClientSocket == INVALID_SOCKET)continue;

        //cout<<"Client socket: "<<ClientSocket<<" Connected."<<endl;        

        for(int i = 0; i < 10; i++)
        {
            if(Clients[i] == 0)
            {
                Clients[i] = ClientSocket;
                break;
            }
        }

        for(int i = 0; i < 10; i++)
        {
            cout<<Clients[i]<<" | ";
        }

        cout<<endl;

        CreateThread(0, 0, (LPTHREAD_START_ROUTINE)&ClientReceive, (LPVOID)&ClientSocket, 0, 0);
        CreateThread(0, 0, (LPTHREAD_START_ROUTINE)&ClientSend, (LPVOID)&ClientSocket, 0, 0);
    }

    WSACleanup();

    return 0;
}



Клиент:


Код

#include <winsock2.h>
#include <iostream.h>

DWORD ServerLetter(LPVOID Param)
{
    SOCKET Server = *(SOCKET *)Param;

    while(true)
    {
        char BufferSend[100];

        memset((void *)BufferSend, 0, 100);

        cin>>BufferSend;
        
        send(Server, BufferSend, strlen(BufferSend), 0);
    }

    return -1;
}

int main()
{
    WSADATA Data;
    
    WSAStartup(MAKEWORD(2, 2), &Data);

    SOCKET S = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
  
    sockaddr_in address;
    address.sin_family = AF_INET;
    address.sin_port = htons(2000);
    address.sin_addr.s_addr = inet_addr("127.0.0.1");

    while (true)
    {
    if( connect(S, (sockaddr*)&address, sizeof address))
    {
        cout<<"Server Not Found."<<endl;
        //return -1;

        Sleep(1000);
    }
    else
    {
        goto connected;
    }
    }

connected:

    CreateThread(0, 0, (LPTHREAD_START_ROUTINE)&ServerLetter, (LPVOID)&S, 0, 0);
    
    while(true)
    {
        char BufferReceive[100];

        memset((void *)BufferReceive, 0, 100);
        
        int asc = recv(S, BufferReceive, 100, 0);

        if(asc < 0)
        {
            cout<<"Server Disconnected.";
            return -1;
        }

        cout<<"Server "<<S<<": ";
        cout<<BufferReceive<<endl;
    }

    WSACleanup();
    return 0;
}

PM MAIL   Вверх
Олег2005
Дата 14.1.2008, 12:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Завсегдатай
Сообщений: 421
Регистрация: 26.5.2005
Где: Рига Латвия

Репутация: 6
Всего: 11



Надо пробовать использовать режим Overlapped -  в нем можно одновременно и слать и принимать
PM MAIL WWW MSN   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Сети | Следующая тема »


 




[ Время генерации скрипта: 0.0880 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.