Em đang tìm hiểu về web socket sử dụng C++ và thư viên Winsock2. Khi chạy chương trình em thấy server thì chạy được nhưng client lại không thể kết nối đến server này ạ anh chị xem giúp em với ạ. Em cảm ơn!!
Đây là code Server:
#include <winsock2.h>
#include <ws2tcpip.h>
#include <string>
#include <thread>
#include <vector>
#include <cstdlib>
using namespace std;
#pragma comment (lib, "Ws2_32.lib")
#define IP_ADDRESS "10.2.32.74"
#define DEFAULT_PORT "3504"
#define DEFAULT_BUFLEN 512
struct client_type
{
int id;
SOCKET socket;
};
const char OPTION_VALUE = 1;
const int MAX_CLIENTS = 1;
//Function Prototypes
//int main();
int process_client(client_type &new_client, vector<client_type> &client_array, thread &thread)
{
string msg = "";
char tempmsg[DEFAULT_BUFLEN] = "";
//Session
while (1)
{
memset(tempmsg, 0, DEFAULT_BUFLEN);
if (new_client.socket != 0)
{
int iResult = recv(new_client.socket, tempmsg, DEFAULT_BUFLEN, 0);
if (iResult != SOCKET_ERROR)
{
if (strcmp("", tempmsg))
msg = "Client #" + to_string(new_client.id) + ": " + tempmsg;
cout << msg.c_str() << endl;
//Broadcast that message to the other clients
for (int i = 0; i < MAX_CLIENTS; i++)
{
if (client_array[i].socket != INVALID_SOCKET)
if (new_client.id != i)
iResult = send(client_array[i].socket, msg.c_str(), strlen(msg.c_str()), 0);
}
}
else
{
msg = "Client #" + to_string(new_client.id) + " Disconnected";
cout << msg << std::endl;
closesocket(new_client.socket);
closesocket(client_array[new_client.id].socket);
client_array[new_client.id].socket = INVALID_SOCKET;
//Broadcast the disconnection message to the other clients
for (int i = 0; i < MAX_CLIENTS; i++)
{
if (client_array[i].socket != INVALID_SOCKET)
iResult = send(client_array[i].socket, msg.c_str(), strlen(msg.c_str()), 0);
}
break;
}
}
} //end while
thread.detach();
return 0;
}
int main()
{
WSADATA wsaData;
int iResult;
string sResult;
struct addrinfo hints;
struct addrinfo *server = NULL;
SOCKET server_socket = INVALID_SOCKET;
std::string msg = "";
std::vector<client_type> client(MAX_CLIENTS);
int num_clients = 0;
int temp_id = -1;
std::thread my_thread[MAX_CLIENTS];
//Initialize Winsock
cout << "Intializing Winsock..." << std::endl;
iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult != 0)
{
cout << "failed" << iResult << endl;
return 1;
}
//Setup hints
ZeroMemory(&hints, sizeof(hints));
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
hints.ai_flags = AI_PASSIVE;
//Setup Server
cout << "Setting up server..." << endl;
iResult = getaddrinfo(static_cast<LPCTSTR>(IP_ADDRESS), DEFAULT_PORT, &hints, &server);
if (iResult != 0)
{
cout << "failed with error" << iResult << endl;
WSACleanup();
return 1;
}
//Create a listening socket for connecting to server
std::cout << "Creating server socket..." << std::endl;
server_socket = socket(server->ai_family, server->ai_socktype, server->ai_protocol);
if (server_socket == INVALID_SOCKET) {
cout << "error" << WSAGetLastError() << endl;
freeaddrinfo(server);
closesocket(server_socket);
WSACleanup();
return 1;
}
//Setup socket options
setsockopt(server_socket, SOL_SOCKET, SO_REUSEADDR, &OPTION_VALUE, sizeof(int)); //Make it possible to re-bind to a port that was used within the last 2 minutes
setsockopt(server_socket, IPPROTO_TCP, TCP_NODELAY, &OPTION_VALUE, sizeof(int)); //Used for interactive programs
//Assign an address to the server socket.
std::cout << "Binding socket..." << std::endl;
bind(server_socket, server->ai_addr, (int)server->ai_addrlen);
//Listen for incoming connections.
std::cout << "Listening..." << std::endl;
listen(server_socket, SOMAXCONN);
/*if (listen(server_socket, SOMAXCONN) == SOCKET_ERROR)
{
cout << "listen failed" << WSAGetLastError() << endl;
closesocket(server_socket);
WSACleanup();
return 1;
}*/
//Initialize the client list
for (int i = 0; i < MAX_CLIENTS; i++)
{
client[i] = { -1, INVALID_SOCKET };
}
while (1)
{
SOCKET incoming = INVALID_SOCKET;
incoming = accept(server_socket, NULL, NULL);
if (incoming == INVALID_SOCKET) continue;
//Reset the number of clients
num_clients = -1;
//Create a temporary id for the next client
temp_id = -1;
for (int i = 0; i < MAX_CLIENTS; i++)
{
if (client[i].socket == INVALID_SOCKET && temp_id == -1)
{
client[i].socket = incoming;
client[i].id = i;
temp_id = i;
}
if (client[i].socket != INVALID_SOCKET)
num_clients++;
//std::cout << client[i].socket << std::endl;
}
if (temp_id != -1)
{
//Send the id to that client
std::cout << "Client #" << client[temp_id].id << " Accepted" << std::endl;
msg = std::to_string(client[temp_id].id);
send(client[temp_id].socket, msg.c_str(), strlen(msg.c_str()), 0);
//Create a thread process for that client
my_thread[temp_id] = std::thread(process_client, std::ref(client[temp_id]), std::ref(client), std::ref(my_thread[temp_id]));
}
else
{
msg = "Server is full";
send(incoming, msg.c_str(), strlen(msg.c_str()), 0);
std::cout << msg << std::endl;
}
} //end while
//Close listening socket
closesocket(server_socket);
//Close client socket
for (int i = 0; i < MAX_CLIENTS; i++)
{
my_thread[i].detach();
closesocket(client[i].socket);
}
//Clean up Winsock
WSACleanup();
std::cout << "Program has ended successfully" << std::endl;
//system("pause");
return 0;
}```
Đây là code client:
```#include <winsock2.h>
#include <ws2tcpip.h>
#include <iostream>
#include <string>
#include <thread>
using namespace std;
#pragma comment (lib, "Ws2_32.lib")
#define DEFAULT_BUFLEN 512
#define IP_ADDRESS "10.2.32.74"
#define DEFAULT_PORT "3504"
struct client_type
{
SOCKET socket;
int id;
char received_message[DEFAULT_BUFLEN];
};
int process_client(client_type &new_client)
{
while (1)
{
memset(new_client.received_message, 0, DEFAULT_BUFLEN);
if (new_client.socket != 0)
{
int iResult = recv(new_client.socket, new_client.received_message, DEFAULT_BUFLEN, 0);
if (iResult != SOCKET_ERROR)
cout << new_client.received_message << endl;
else
{
cout << "recv() failed: " << WSAGetLastError() << endl;
break;
}
}
}
if (WSAGetLastError() == WSAECONNRESET)
cout << "The server has disconnected" << endl;
return 0;
}
int main()
{
//thread(client_type, );
WSAData wsa_data;
struct addrinfo *result = NULL, *ptr = NULL, hints;
string sent_message = "";
client_type client = { INVALID_SOCKET, -1, "" };
int iResult = 0;
string message;
cout << "Starting Client...\n";
// Initialize Winsock
iResult = WSAStartup(MAKEWORD(2, 2), &wsa_data);
if (iResult != 0) {
cout << "WSAStartup() failed with error: " << iResult << endl;
return 1;
}
ZeroMemory(&hints, sizeof(hints));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
cout << "Connecting...\n";
// Resolve the server address and port
iResult = getaddrinfo(static_cast<LPCTSTR>(IP_ADDRESS), DEFAULT_PORT, &hints, &result);
if (iResult != 0) {
cout << "getaddrinfo() failed with error: " << iResult << endl;
WSACleanup();
system("pause");
return 1;
}
// Attempt to connect to an address until one succeeds
for (ptr = result; ptr != NULL; ptr = ptr->ai_next) {
// Create a SOCKET for connecting to server
client.socket = socket(ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol);
if (client.socket == INVALID_SOCKET) {
cout << "socket() failed with error: " << WSAGetLastError() << endl;
WSACleanup();
system("pause");
return 1;
}
// Connect to server.
iResult = connect(client.socket, ptr->ai_addr, (int)ptr->ai_addrlen);
//cout << iResult << endl;
//system("pause");
//cout << ptr<<endl;
if (iResult == SOCKET_ERROR) {
//closesocket(client.socket);
iResult = connect(client.socket, ptr->ai_addr, (int)ptr->ai_addrlen);
//cout<< WSAGetLastError() <<endl;
//cout << SOCKET_ERROR << endl;
client.socket = INVALID_SOCKET;
//continue;
}
//break;
}
freeaddrinfo(result);
if (client.socket == INVALID_SOCKET) {
//cout << INVALID_SOCKET << endl;
cout << "Unable to connect to server!" /*<<"\n"<< WSAGetLastError()*/ << endl;
WSACleanup();
system("pause");
return 1;
}
cout << "Successfully Connected" << endl;
//Obtain id from server for this client;
recv(client.socket, client.received_message, DEFAULT_BUFLEN, 0);
message = client.received_message;
if (message != "Server is full")
{
client.id = atoi(client.received_message);
thread my_thread(process_client, ref(client));
while (1)
{
getline(cin, sent_message);
iResult = send(client.socket, sent_message.c_str(), strlen(sent_message.c_str()), 0);
if (iResult <= 0)
{
cout << "send() failed: " << WSAGetLastError() << endl;
break;
}
}
//Shutdown the connection since no more data will be sent
my_thread.detach();
}
else
cout << client.received_message << endl;
cout << "Shutting down socket..." << endl;
iResult = shutdown(client.socket, SD_SEND);
if (iResult == SOCKET_ERROR) {
cout << "shutdown() failed with error: " << WSAGetLastError() << endl;
closesocket(client.socket);
WSACleanup();
system("pause");
return 1;
}
closesocket(client.socket);
WSACleanup();
system("pause");
return 0;
}```