Форум программистов, компьютерный форум, киберфорум
C++: Сети
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.57/35: Рейтинг темы: голосов - 35, средняя оценка - 4.57
1 / 1 / 0
Регистрация: 07.05.2015
Сообщений: 79
1

Чат на сокетах

26.07.2015, 20:31. Просмотров 6618. Ответов 17
Метки нет (Все метки)

Я создаю чат на С ++, только такой в котором 1 сервер который как и клиент также может отправлять и принимать сообщения и 1 клиент.И я не как не могу сделать так, чтобы клиент в любое время мог принимать сообщения от сервера даже когда клиент набирает сообщение серверу. Как сделать так чтобы одновременно можно было получать, даже когда пишешь.
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
26.07.2015, 20:31
Ответы с готовыми решениями:

Чат на сокетах
Есть сервер и клиент когда отправляешь сообщение с первого клиента втором то сообщения не...

Простой чат на сокетах
Доброго времени суток. Имеется VDS сервер с установленной на нём ОС Linux, на моём пк установлен...

О сокетах
Здравствуйте, возникло пару вопросов о сокетах. 1)Создаю я сервер и жду конекта, accept принимаю...

SDP на TCP сокетах
Всем привет. Написал приложение использующее TCP сокеты, теперь нужно чтобы по протоколу SDP оно...

17
Модератор
3308 / 2099 / 333
Регистрация: 13.01.2012
Сообщений: 8,156
26.07.2015, 20:38 2
Цитата Сообщение от Restomix Посмотреть сообщение
Как сделать
взять и сделать. где именно проблема? для примера: вы не можете так сделать потому что...
1 у вас консоль
2 вы не проверяете есть ли входящие данные до тех пор пока пользователь не пошлет сообщение
3 что-то свое
1
++Ͻ
16400 / 9471 / 1825
Регистрация: 27.09.2012
Сообщений: 23,359
Записей в блоге: 2
26.07.2015, 21:28 3
http://www.boost.org/doc/libs/1_58_0..._examples.html
1
1 / 1 / 0
Регистрация: 07.05.2015
Сообщений: 79
28.07.2015, 17:32  [ТС] 4
vxg, первое и второе.Как мне в одно же время слушать посылать ?
0
73 / 73 / 18
Регистрация: 29.11.2011
Сообщений: 348
28.07.2015, 17:53 5
А код какой-то уже создан? Или пока создаются только планы по созданию?

Добавлено через 50 секунд
Цитата Сообщение от Restomix Посмотреть сообщение
одно же время слушать посылать ?
в двух потоках, либо nonblocking socket
1
Модератор
3308 / 2099 / 333
Регистрация: 13.01.2012
Сообщений: 8,156
29.07.2015, 23:22 6
Цитата Сообщение от Restomix Посмотреть сообщение
vxg, первое и второе
не долго думая суем прием и передачу в разные консоли... Прием пакетов по UDP
1
1 / 1 / 0
Регистрация: 07.05.2015
Сообщений: 79
30.07.2015, 15:00  [ТС] 7
#server-client
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
#include <iostream>
#include <windows.h>
#include <winsock2.h>
#include <string>
using namespace std;
 
int main()
{   
    WSADATA WsaData;
    int error=WSAStartup(0x0202,&WsaData);
    
    if(error==SOCKET_ERROR)
    {
        cout<<"WsaData_ERROR";
        return 0;
    }
    
    SOCKET mysocket;
    mysocket=socket(AF_INET,SOCK_STREAM,0);
    
    if(mysocket==-1)
    {
        cout<<"SocketError";
    }
    
    sockaddr_in my_addr;
    my_addr.sin_family=AF_INET;
    my_addr.sin_port=htons(7710);
    my_addr.sin_addr.s_addr=0;
    
    error=bind(mysocket,(sockaddr*) &my_addr, sizeof(my_addr));
    
    if(error == -1)
    {
        cout<<"bind_ERROR";
    }
    
    listen(mysocket,0x2);
    SOCKET client_socket;
    
    client_socket=socket(AF_INET,SOCK_STREAM,0);
    sockaddr_in addr_klient;
    int number_k=0;
    int size_k=sizeof(addr_klient);
    
    cout<<"listening...";
    
    client_socket=accept(mysocket,(sockaddr*)&addr_klient,&size_k);
    
    if(client_socket<0)
    {
        cout<<"accept_EROR";
    }
    
    //отправка и прием 
    char buffer[1024];
    cout<<"Your name: ";
    gets(buffer);
    buffer[strlen(buffer)]=':';
    while(1)
    {   
        int longg=strlen(buffer);
        gets(buffer+longg);
        send(client_socket,&buffer[0],strlen(buffer),0);
        for(int i=0;buffer[longg+i]!='\0';i++)
        {
            buffer[longg+i]=NULL;
        }
    }
    return 0;
    }
#client
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
#include <iostream>
#include <windows.h>
#include <winsock2.h>
#include <string>
using namespace std;
int main()
{
    WSADATA WsaData;
    int error=WSAStartup(0x0202,&WsaData);
    
    if(error==SOCKET_ERROR)
    {
        cout<<"WsaData_ERROR";
        return 0;
    }
    
    SOCKET mysocket;
    mysocket=socket(AF_INET,SOCK_STREAM,0);
    
    if(mysocket==-1)
    {
        cout<<"SocketError";
    }
    
    sockaddr_in my_addr;
    my_addr.sin_family = AF_INET;
    my_addr.sin_port = htons(7710);
    my_addr.sin_addr.S_un.S_addr = inet_addr("130.185.59.101");
    
    cout<<"Connecting...";
    
    if(error=connect(mysocket, (struct sockaddr *)&my_addr, sizeof(struct sockaddr))==0)
    {
        cout<<"Bind with server true";
    }
 
    //прием и отправка
    char buffer[1024];
    while(1)
    {
        recv(mysocket,&buffer[0],sizeof(buffer),0);
        cout<<buffer<<"\n";
        for(int i=0;buffer[i]!='\0';i++)
        {
            buffer[i]=NULL;
        }
    }
    
    return 0;
}
Добавлено через 4 минуты
Как это в двух потоках, то есть DWORD WINAPI?Дай какой-то пример пожалуйста.
0
73 / 73 / 18
Регистрация: 29.11.2011
Сообщений: 348
30.07.2015, 16:53 8
А у тебя что, сервер только посылает, а клиент только слушает?
1
1 / 1 / 0
Регистрация: 07.05.2015
Сообщений: 79
30.07.2015, 17:39  [ТС] 9
я могу дописать в сервер recv а в клиент send.Но смысл не в том, как мне в одно же время слушать и посылать ?
0
150 / 137 / 35
Регистрация: 29.07.2012
Сообщений: 709
30.07.2015, 21:45 10
Цитата Сообщение от Restomix Посмотреть сообщение
я могу дописать в сервер recv а в клиент send.Но смысл не в том, как мне в одно же время слушать и посылать ?
Один сокет в потоке слушает, второй принимает в главном треде. Прежде чем сесть за задачу разбейте ее на части и решайте ее частями. Вам советую сначала прочитать литературу про TCP/IP, Thread и т.п. вещи.
1
73 / 73 / 18
Регистрация: 29.11.2011
Сообщений: 348
31.07.2015, 03:30 11
Меня больше затрудняет одновременный ввод с клавиатуры в одном потоке и вывод на экран в другом
1
1 / 1 / 0
Регистрация: 07.05.2015
Сообщений: 79
31.07.2015, 10:23  [ТС] 12
это наверно на c ++ не реально сделать.Сколько перечитал подобных примеров не видел
0
73 / 73 / 18
Регистрация: 29.11.2011
Сообщений: 348
31.07.2015, 13:03 13
Сервер:
Кликните здесь для просмотра всего текста

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
#include <iostream>
#include <windows.h>
#include <string>
using namespace std;
 
DWORD WINAPI recvthread(LPVOID param)
{
 char inbuf[1024];
 SOCKET sock = *(SOCKET*)param;
 while(1)
 {
  int recvres = recv(sock, inbuf, 1023, 0);
  if(recvres == SOCKET_ERROR)break; //что-то пошло не по плану
  inbuf[recvres] = 0;
  //////////////////////////////////////////
  printf("%s", inbuf);//нужна альтернатива//
  //////////////////////////////////////////
 
 };
 return(-1);
};
 
int main()
{   
    WSADATA WsaData;
    int error=WSAStartup(0x0202,&WsaData);
    
    if(error==SOCKET_ERROR)
    {
        cout<<"WsaData_ERROR";
        WSACleanup();
        return 0;
    }
    
    SOCKET mysocket;
    mysocket=socket(AF_INET,SOCK_STREAM,0);
    
    if(mysocket==-1)
    {
        cout<<"SocketError";
        WSACleanup();
        return 0;
    }
    
    sockaddr_in my_addr;
    my_addr.sin_family=AF_INET;
    my_addr.sin_port=htons(7710);
    my_addr.sin_addr.s_addr=0;
    
    error=bind(mysocket,(sockaddr*) &my_addr, sizeof(my_addr));
    
    if(error == -1)
    {
        cout<<"bind_ERROR";
        WSACleanup();
        return 0;
    }
    
    listen(mysocket,0x2);
    SOCKET client_socket;
    
    //client_socket=socket(AF_INET,SOCK_STREAM,0); - эта строка НЕ НУЖНА, тебе accept и так сокет создаст и вернет
    sockaddr_in addr_klient;
    int number_k=0;
    int size_k=sizeof(addr_klient);
    
    cout<<"listening...";
    
    client_socket=accept(mysocket,(sockaddr*)&addr_klient,&size_k);
    closesocket(mysocket);
    if(client_socket<0)
    {
        cout<<"accept_EROR";
        WSACleanup();
        return 0;
    }
    
    //отправка и прием 
    char buffer[1024];
    cout<<"Your name: ";
    gets(buffer);//странный выбор, cin мож тогда уже?
    int longg=strlen(buffer);
    buffer[longg++]=':';
 
    CreateThread(0, 0, recvthread, (LPVOID)&client_socket, 0, 0);//создаем собственно поток кторый слушает чо прийдет
    
    
    while(1)//а этот цикл в основном потоке отправляет в сеть то что мы напичатали
    {   
        /////////////////////////////////////////
        gets(buffer+longg);//нужна альтернатива//да и за границы массива можно выйти
        /////////////////////////////////////////
        strcat(buffer, "\n");
 
 
        if(SOCKET_ERROR == send(client_socket, buffer, strlen(buffer) + 1/*null-terminated string посылаем же*/, 0))
          break;
    }
 
    WSACleanup();//второй поток закрывать не нужно, так как после WSACleanup recv вернет SOCKET_ERROR и поток автоматом закроется
    return -1;
}

клиент:
Кликните здесь для просмотра всего текста

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
#include <iostream>
#include <windows.h>
#include <string>
using namespace std;
 
DWORD WINAPI recvthread(LPVOID param)
{
 char inbuf[1024];
 SOCKET sock = *(SOCKET*)param;
 while(1)
 {
  int recvres = recv(sock, inbuf, 1024, 0);
  if(recvres == SOCKET_ERROR)break; //что-то пошло не по плану
 
  //////////////////////////////////////////
  printf("%s", inbuf);//нужна альтернатива//
  //////////////////////////////////////////
 
 };
 return(-1);
};
 
int main()
{   
    WSADATA WsaData;
    int error=WSAStartup(0x0202,&WsaData);
    
    if(error==SOCKET_ERROR)
    {
        cout<<"WsaData_ERROR";
        return 0;
    }
    
    SOCKET mysocket;
    mysocket=socket(AF_INET,SOCK_STREAM,0);
    
    if(mysocket==-1)
    {
        cout<<"SocketError";
    }
    
    sockaddr_in my_addr;
    my_addr.sin_family=AF_INET;
    my_addr.sin_port=htons(7710);
    my_addr.sin_addr.s_addr=inet_addr("127.0.0.1");  
    
    if(SOCKET_ERROR == connect(mysocket, (SOCKADDR*)&my_addr, sizeof(my_addr)))
    {
      cout << "connect error";
      WSACleanup();
      return 0;
    };
 
    
    //отправка и прием 
    char buffer[1024];
    cout<<"Your name: ";
    gets(buffer);
    int longg=strlen(buffer);
    buffer[longg++]=':';
 
    CreateThread (0, 0, recvthread, (LPVOID)&mysocket, 0, 0);
 
    while(1)
    {   
        gets(buffer+longg);
        strcat(buffer, "\n");
 
        if(SOCKET_ERROR == send(mysocket, buffer, strlen(buffer) + 1, 0))
          break;
        buffer[longg]=0;
    }
    WSACleanup();
    return -1;
}
2
73 / 73 / 18
Регистрация: 29.11.2011
Сообщений: 348
31.07.2015, 13:08 14
скрин =)
1
Миниатюры
Чат на сокетах  
1 / 1 / 0
Регистрация: 07.05.2015
Сообщений: 79
31.07.2015, 15:07  [ТС] 15
Спасибо большое, очень помог.
C++
1
2
if(SOCKET_ERROR == send(client_socket, buffer, strlen(buffer) + 1/*null-terminated string посылаем же*/, 0))
          break;
То есть если мы ничего не пишем цикл перерываем.
0
73 / 73 / 18
Регистрация: 29.11.2011
Сообщений: 348
31.07.2015, 15:31 16
если send возвращает SOCKET_ERROR - значит дисконнект, либо еще какая-нибудь оказия. Да, просто прерываем цикл и прога закрывается

Добавлено через 10 минут
если тебе что-то присылают, когда ты начал печатать, будет глюк.
1
1 / 1 / 0
Регистрация: 07.05.2015
Сообщений: 79
31.07.2015, 18:10  [ТС] 17
если мне что-то присылают, и я тогда начал печатать я уже не смогу редактировать то что написал оно летит в буфер и следущий gets его дополняет.То есть я смогу буфер обнулить или же не как не смогу редактировать правильно другого выхода нету для консоли?
0
22 / 22 / 8
Регистрация: 03.12.2013
Сообщений: 144
17.07.2019, 15:02 18
Спасибо за работающий пример в 13 сообщении. Через несколько минут (10 - 20) происходит разрыв соединения (на отдельном ПК, со статическим IP). Как устранить самопроизвольный disconnect ? Заранее спасибо за ответ.
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
17.07.2019, 15:02

Заказываю контрольные, курсовые, дипломные и любые другие студенческие работы здесь.

Алгоритм сервера на сокетах
Помогите пожалуйста, только начал копаться в socket`aх. Уже создал простой &quot;эхо&quot; сервер и клиент к...

Многопоочност в сокетах VCL
Пишу приложене типа клиент-сервер, пр этом универсальное, то есть каждый хост в сети является...

Клиент и сервера на сокетах
Пытаюсь изучить Winsock, вот написал клиент и сервер. Сервер не дожидаясь запроса на подключение...

Нужна литература о сокетах
Доброго времени суток! Можете посоветовать какую-нибудь литературу по поводу сокетов в СИ++. В...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
18
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2020, vBulletin Solutions, Inc.