Форум программистов, компьютерный форум CyberForum.ru

отправка сообщений по TCP на одном компьютере - C++

Восстановить пароль Регистрация
 
Leardjiny
0 / 0 / 1
Регистрация: 22.09.2013
Сообщений: 102
11.03.2016, 15:03     отправка сообщений по TCP на одном компьютере #1
Добрый день.
Хочу сделать что то типа соединения клиент-сервер но на одном компьютере.

Соответственно делаю соединение по адресу 127.0.0.1 и порту 3000

Возникает такая проблема - когда запускаю соединение, все работает, данные отсылаются и все отлично.
А если открываю например браузер, то все сразу ломается, данные перестают приниматься.
Подскажите пожалуйста, в чем может быть проблема и как ее исправить?

Код сервера:
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
103
104
105
106
107
108
bool CNetServer::Start(unsigned long iface, unsigned short port, unsigned connectionmode)
{   
    Stop();
 
    m_connectionmode = connectionmode;
 
    int result = WSAStartup(MAKEWORD(2, 2), &m_socket_data);
    if (result != NO_ERROR)
    {
        Log(LOG_ERROR, TEXT("CNetServer::Start() - WSAStartup() failed with error: %d"), result);
        return false;
    }
 
    SOCKET listen_socket = socket(AF_INET, SOCK_STREAM, 0);
    if (listen_socket == INVALID_SOCKET)
    {
        Log(LOG_ERROR, TEXT("CNetServer::Start() - socket() function failed with error: %ld"),
            WSAGetLastError());
        Stop();
        return false;
    }
    sockaddr_in addr;
    memset(&addr, 0, sizeof(sockaddr_in));
    addr.sin_addr.S_un.S_addr = iface;
    addr.sin_port = htons(port);
    addr.sin_family = AF_INET;
    {
        result = bind(listen_socket, reinterpret_cast< SOCKADDR* >(&addr), sizeof (SOCKADDR));
        if (result == SOCKET_ERROR)
        {
            Log(LOG_ERROR, TEXT("CNetServer::Start() - bind() function failed with error %d"),
                WSAGetLastError());
            Stop();
            return false;
        }
 
        if (listen(listen_socket, SOMAXCONN) == SOCKET_ERROR)
        {
            Log(LOG_ERROR, TEXT("CNetServer::Start() - listen() function failed with error %d"),
                WSAGetLastError());
            Stop();
            return false;
        }
 
        {
            CSingleLock lock(&m_lock, TRUE);
 
            m_listen_socket = listen_socket;
            m_iface = iface;
            m_port = port;          
 
            m_thread_exit_event = 0;                
        }
 
        // Start listening thread
        m_thread = reinterpret_cast< HANDLE >(_beginthreadex(   0,
            0,
            ListenThread, 
            reinterpret_cast< void* >(this),
            0,  
            0));
        if (!m_thread)
        {
            Log(LOG_ERROR, TEXT("CNetServer::Start() - Failed to start thread"));
            Stop();
            return false;
        }
 
    }
    
    return true;
}
 
//отправка
 
void CNetServer::SendPacket(const void* packet, const long size)
{
    if (!packet || size <= 0)
        return;
 
    CSingleLock lock(&m_lock, true);
 
    Clients::const_iterator client_iterator = m_clients.begin();
    Clients::const_iterator client_end = m_clients.end();
    for (; client_end != client_iterator;)
    {
        std::tr1::shared_ptr< Client > client = *client_iterator;
        if (client)
        {
            if (client->dropped() < m_max_dropped)
            {
                (*client_iterator)->Send(packet, size);
                ++client_iterator;
                continue;
            }           
        }       
 
        in_addr addr;
        addr.S_un.S_addr = client->address();
        Log(LOG_INFO, TEXT("Client(%s:%d) disconnected (dropped %d, last error %d)"),
            CString(inet_ntoa(addr)),
            client->port(),
            client->dropped(),
            client->last_error()
            );
        client_iterator = m_clients.erase(client_iterator);
    }
}

код клиента

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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
bool CTcpClient::StartConnect()
{
    //Init socket
    m_listenSocket = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, WSA_FLAG_OVERLAPPED);
    if (m_listenSocket == INVALID_SOCKET) 
    {
        if (m_pLogger)
            m_pLogger->Log(logger::LL_ERROR, L"Can't create socket. %s", GetLastErrorText());
    };
 
    if (m_listenSocket == INVALID_SOCKET)
        return false;
 
    struct  sockaddr_in sin;
 
    // bind local address and port number
    memset((void *)&sin, 0, sizeof(sin));
    sin.sin_family = AF_INET;
    sin.sin_addr.s_addr = inet_addr(FPGA_IP_ADDR);
    sin.sin_port = htons((u_short)TCP_PORT);
 
    timeval tv;
    tv.tv_sec  = NET_CONNECT_TIMEOUT/1000;
    tv.tv_usec = 0;
 
    unsigned long iMode = 1;
    ioctlsocket(m_listenSocket, FIONBIO, &iMode);
 
    // Connect to server.
    if ( connect( m_listenSocket, (SOCKADDR*) &sin, sizeof(sin) ) == false)
    {
        if (m_pLogger)
            m_pLogger->Log(logger::LL_ERROR, L"Failed to connect to server: %S port: %i...",
                            inet_ntoa(sin.sin_addr), TCP_PORT);
        return false;
    }
 
    // restart the socket mode
    iMode = 0;
    ioctlsocket(m_listenSocket, FIONBIO, &iMode);
 
    fd_set Write, Err;
    FD_ZERO(&Write);
    FD_ZERO(&Err);
    FD_SET(m_listenSocket, &Write);
    FD_SET(m_listenSocket, &Err);
 
    // check if the socket is ready
    select(0, NULL, &Write, &Err, &tv);         
    if (FD_ISSET(m_listenSocket, &Write)) 
    {   
        setsockopt(m_listenSocket, SOL_SOCKET, SO_RCVTIMEO, (char*)&tv, sizeof(tv));
        setsockopt(m_listenSocket, SOL_SOCKET, SO_SNDTIMEO, (char*)&tv, sizeof(tv));
 
        if (m_pLogger)
            m_pLogger->Log(logger::LL_OK, L"Client's connected to server: %S port: %i...",
                            inet_ntoa(sin.sin_addr), TCP_PORT);
        m_acceptSocket = m_listenSocket;
 
        m_startTime = 0;//timeGetTime(); // for calculation transfer rate
 
        //Set up an overlapped structure
        m_eventArray[0] = WSACreateEvent();
 
        //test data
 
        m_transferRate = 0.f;
        m_packCount = 0;
        m_overlapInit = false;
        m_firstPack   = true;
        m_FPGAFrameLost = 0;
 
        num_bytes = 0;
 
        return true;
    }
    else
    {
        return false;
    }
}
 
 
//прием
 
int CTcpClient::Poll(void** pBuf, size_t &nLength, DWORD &time)
{
    if ((pBuf)== NULL )return 0;
 
    int     res         = 0;
    bool    dataReady   = false;
    bool    dataProcessing = true;
 
 
    //////////////////////////////////////////////////////////////////////////
    // Initialization & checkout
    if (m_overlapInit)
    {   
        DWORD IndexEvent = 0xffffffff;
        //Wait for the overlapped I/O call to complete
        IndexEvent = WSAWaitForMultipleEvents(1,m_eventArray, FALSE, 1, FALSE);
        if ( IndexEvent != WSA_WAIT_FAILED  && IndexEvent != WSA_WAIT_TIMEOUT && IndexEvent == 0)
        {
            dataReady = true;
            m_overlapInit = false;
            //  Determine the status of the overlapped
            m_recvdBytes = 0;
            WSAGetOverlappedResult(m_acceptSocket, &m_acceptOverlapped, &m_recvdBytes, FALSE, &m_recvdFlags);
            if (m_recvdBytes == 0)
            {
                if (m_pLogger)
                    m_pLogger->Log(logger::LL_WARNING, L"Recevied 0 bytes");
                res =  -1;//need close socket
            }
            //assert(  DSP_FRAMESIZE== 155136);
        }
        else
        {   //mb pending or non pending
            if (IndexEvent == WSA_WAIT_FAILED)
            {
                if (m_pLogger)
                    m_pLogger->Log(logger::LL_ERROR, L"mb pending or non pending %s", GetLastErrorText());
                res = -1;
            }
        }
    } 
    else
    {
        int bytesRecv = 0;
 
        //init Receive      
        memset((void*)&m_acceptOverlapped,0,sizeof(WSAOVERLAPPED));
        
        m_acceptOverlapped.hEvent = m_eventArray[0];
      
        //Set buffers for WSARecv
        do 
        {
            if ( SetReceiveBuf() )
            {
                m_recvdFlags = 0;
                m_recvdBytes = 0;
 
                bytesRecv = WSARecv(m_acceptSocket, &m_WSADataBuf, 1, &m_recvdBytes,
                    &m_recvdFlags, &m_acceptOverlapped, NULL);
                int err = WSAGetLastError();                
                ParseReceivedData(m_recvdBytes);
            }
            else
                break;
        } while ( bytesRecv == 0 );
 
        if (bytesRecv == 0)
        {
            dataReady = true;
            m_overlapInit = false;  
            dataProcessing = false;
        }
        else
        {
            dataReady = false;
            m_overlapInit = true;
            int res_error = WSAGetLastError() ;
            if ((bytesRecv == SOCKET_ERROR) && (res_error != WSA_IO_PENDING) )
            {
                res = WSAerrorAnalysis(WSAGetLastError());
                if (m_pLogger)
                    m_pLogger->Log(logger::LL_ERROR, L"Socket error %s", GetLastErrorText());
            }
            else if (res_error == WSA_IO_PENDING)
                res = 1;
        }
    }
 
    if ( dataReady && res != -1 )
    {
        WSAResetEvent(m_eventArray[0]);
 
        if ( dataProcessing == true)
            ParseReceivedData(m_recvdBytes);
        else
            ParseReceivedData(0);
        if ( GetReceiveBuf(pBuf, nLength, time) )
            res = 1;
    }
    else
    {
        ParseReceivedData(0);
        if ( GetReceiveBuf(pBuf, nLength, time) )
            res = 1;
    }
   
    return res;
}

При приеме клиент возвращает код ошибки 977 - WSA_IO_PENDING.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
11.03.2016, 15:03     отправка сообщений по TCP на одном компьютере
Посмотрите здесь:

Связь по TCP C++
Составить программу, которая находит минимальный элемент и все элементы, расположение в одном ряду и в одном столбце с минимальным меняет на минимальн C++
C++ Работа с TCP/IP протоколами
C++ Отправка и обработка пользовательских сообщений
Написать программу, создающую два потока, которые выполняются в одном адресном пространстве (в одном процессе) C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Убежденный
Системный программист
 Аватар для Убежденный
14200 / 6215 / 986
Регистрация: 02.05.2013
Сообщений: 10,356
Завершенные тесты: 1
11.03.2016, 15:47     отправка сообщений по TCP на одном компьютере #2
Это не ошибка. Так работают асинхронные сокеты.
Не хочешь асинхронные сокеты - убирай флаг WSA_FLAG_OVERLAPPED.
Leardjiny
0 / 0 / 1
Регистрация: 22.09.2013
Сообщений: 102
11.03.2016, 15:52  [ТС]     отправка сообщений по TCP на одном компьютере #3
Если убрать, то на передачу это не повлияет? (клиент у меня пока один несколько пока не интересуют).
И браузер перестанет тогда мешать?

Добавлено через 2 минуты
убрал.
Сделал так:
m_listenSocket = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, 0);

Ситуация не изменилась совсем
Убежденный
Системный программист
 Аватар для Убежденный
14200 / 6215 / 986
Регистрация: 02.05.2013
Сообщений: 10,356
Завершенные тесты: 1
11.03.2016, 15:54     отправка сообщений по TCP на одном компьютере #4
Еще надо убрать OVERLAPPED и все, что связано с "асинхронщиной".
Leardjiny
0 / 0 / 1
Регистрация: 22.09.2013
Сообщений: 102
11.03.2016, 16:03  [ТС]     отправка сообщений по TCP на одном компьютере #5
Да, как только из приема это убрал, все заработало. Спасибою
Yandex
Объявления
11.03.2016, 16:03     отправка сообщений по TCP на одном компьютере
Ответ Создать тему
Опции темы

Текущее время: 08:41. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru