Простой клиент-сервер UDP
05.04.2018, 19:09. Показов 30033. Ответов 1
Метки bind, c, client, client-server app, recv, router, server, socket, udp, visual studio 2017, winsock, winsocket, visual studio ( Все метки)
Всем добрый вечер!
Для осознания, почему контроллер не связывается с компьютером, решил отработать клиент-серверное взаимодействие по UDP в локальной домашней сети. Связал мак-адреса и айпишники компа и ноута в DHCP настройках роутера (ASUS RT-N66U, к слову), на ноуте запускаю сервер, на компе - клиент. В клиентском приложении ввожу ip сервера (какой прописал в DHCP на роутере) и шлю рандомные сообщения (от балды текст набиваю). Сервер молчит и ничего не принимает, голову сломал, что может быть не так. Комп с ноута пингуется, ноут с компа тоже.
Когда подключаю их напрямки, ставлю у компа ip 192.168.1.220, маску 255.255.255.0, шлюз 192.168.1.230.
У ноута ip 192.168.1.230 (он и является шлюзом для компа), маска 255.255.255.0, шлюз оставляю пустым. При таких настройках комп пингуется с ноутбука, но ноутбук не пингуется с компа. Приложения тоже не работают: клиент отправляет сообщения, но сервер в консоли ничего не отображает, просто молчит... Хотелось бы, чтобы через роутер всё же они договорились.
На одной машине запускаю клиент и сервер, в клиенте ввожу айпишник этой же машины (192.168.1.230, например, или 127.0.0.1) - всё работает, аллилуйя! А через роутер компьютер с ноутбуком договориться не могут. Пользуюсь MS Visual Studio 2017. Помогите, кто чем может.
Код сервера:
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
| #include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <iostream>
#include <winsock2.h>
#include <WS2tcpip.h>
#pragma comment(lib, "ws2_32.lib")
using namespace std;
#define BUFSIZE 1024 //buffer
#define SERVER_PORT 54000 //server port #
int main(void)
{
//Initialize WinSocket
int rc;
WSAData data;
WORD ver = MAKEWORD(2, 2);
int wsResult = WSAStartup(ver, &data);
if (wsResult != 0)
{
cerr << "WSAStartup failed, Err #" << wsResult << endl;
cin.get();
return 0;
}
//Creating Socket
SOCKET sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (sock == INVALID_SOCKET)
{
cerr << "Can't create a socket, Err #" << WSAGetLastError() << endl;
cin.get();
WSACleanup();
return 0;
}
int OptVal = 1;
int OptLen = sizeof(int);
rc = setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (const char*)&OptVal, OptLen);
if (rc == SOCKET_ERROR)
{
cerr << "Can't set a sockopt, Err #" << WSAGetLastError() << endl;
cin.get();
WSACleanup();
return 0;
}
else
cout << "Socket option SO_REUSEADDR is ON" << endl;
//Fill in a server hint structure
struct sockaddr_in server_addr;
int server_len = sizeof(server_addr);
ZeroMemory(&server_addr, server_len);
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(SERVER_PORT);
server_addr.sin_addr.S_un.S_addr = INADDR_ANY;
rc = bind(sock, (struct sockaddr*)&server_addr, server_len);
if (rc == SOCKET_ERROR)
{
cerr << "Can't bind a socket, Err #" << WSAGetLastError() << endl;
cin.get();
WSACleanup();
return 0;
}
struct sockaddr_in client_addr;
int client_len = sizeof(client_addr);
ZeroMemory(&client_addr, client_len);
//Do-While Loop to send and recieve data
char buf[BUFSIZE];
string userInput;
while (true)
{
ZeroMemory(buf, BUFSIZE);
//Wait for the message
int bytesRecieved = recvfrom(sock, buf, BUFSIZE, 0, (struct sockaddr*)&client_addr, &client_len);
if (bytesRecieved == SOCKET_ERROR)
{
cerr << "Error recieving from client" << WSAGetLastError() << endl;
continue;
}
//Show info
char clientIP[256];
ZeroMemory(clientIP, 256);
inet_ntop(AF_INET, &client_addr.sin_addr, clientIP, 256);
cerr << "Msg from " << clientIP << " : " << ntohs(client_addr.sin_port) << " $ " << buf << endl;
int sendResult = sendto(sock, buf, BUFSIZE, 0, (sockaddr *) &client_addr, client_len);
if (sendResult == SOCKET_ERROR)
{
cerr << "Can't send msg, Err #" << WSAGetLastError() << endl;
}
}
//Shutdown the connection
cin.get();
closesocket(sock);
WSACleanup();
return 0;
} |
|
Код клиента:
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
| #include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <iostream>
#include <winsock2.h>
#include <WS2tcpip.h>
#pragma comment(lib, "ws2_32.lib")
using namespace std;
#define BUFSIZE 1024 //buffer
#define SERVER_PORT 54000 //server port #
int main(void)
{
//Initialize WinSocket
WSAData data;
WORD ver = MAKEWORD(2, 2);
int wsResult = WSAStartup(MAKEWORD(2, 2), &data);
if (wsResult != 0)
{
cerr << "WSAStartup failed, Err #" << wsResult << endl;
cin.get();
return 0;
}
//Creating Socket
SOCKET sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (sock == INVALID_SOCKET)
{
cerr << "Can't create a socket, Err #" << WSAGetLastError() << endl;
cin.get();
WSACleanup();
return 0;
}
int OptVal = 1;
int OptLen = sizeof(int);
int rc = setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (const char*)&OptVal, OptLen);
if (rc == SOCKET_ERROR)
{
cerr << "Can't set a sockopt, Err #" << WSAGetLastError() << endl;
cin.get();
WSACleanup();
return 0;
}
else
cout << "Socket option SO_REUSEADDR is ON" << endl;
//Prompt to type an IP of server
cout << "IP adress of server : ";
string ipAdress;
getline(cin, ipAdress);
//Fill in server and client structures
sockaddr_in server_addr, client_addr;
int server_len = sizeof(server_addr);
ZeroMemory(&server_addr, server_len);
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(SERVER_PORT);
inet_pton(AF_INET, ipAdress.c_str(), &server_addr.sin_addr);
int client_len = sizeof(client_addr);
ZeroMemory(&client_addr, client_len);
client_addr.sin_family = AF_INET;
client_addr.sin_port = htons(0);
client_addr.sin_addr.S_un.S_addr = INADDR_ANY;
rc = bind(sock, (struct sockaddr*)&client_addr, client_len);
if (rc == SOCKET_ERROR)
{
cerr << "Can't bind a socket, Err #" << WSAGetLastError() << endl;
cin.get();
WSACleanup();
return 0;
}
//Do-While Loop to send and recieve data
char buf[BUFSIZE];
string userInput;
do
{
//Prompt to type some text
cout << "> ";
getline(cin, userInput);
if (userInput.size() > 0)
{
//Send the text
int sendResult = sendto(sock, userInput.c_str(), BUFSIZE, 0, (sockaddr*)&server_addr, server_len);
if (sendResult == SOCKET_ERROR)
{
cerr << "Can't send msg, Err #" << WSAGetLastError() << endl;
cin.get();
return 0;
}
/*
//Wait for response
ZeroMemory(buf, BUFSIZE);
int bytesRecieved = recvfrom(sock, buf, BUFSIZE, 0, (struct sockaddr*) NULL, NULL);
if (bytesRecieved > 0)
{
//Echo the text to the console
cerr << "SERVER> " << string(buf, 0, bytesRecieved) << endl;
}
else
{
cerr << "Can't read msg, Err #" << WSAGetLastError() << endl;
cin.get();
return 0;
}
*/
}
} while (userInput.size() > 0);
//Shutdown the connection
cin.get();
closesocket(sock);
WSACleanup();
return 0;
} |
|
0
|