I have an issues of connecting to my UDP server. On VS it showed no errors except when I do an error checking it give me a Error 10057.
UDP Client:
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#include <Winsock2.h>
#include <ws2tcpip.h>
#include <stdio.h>
#include <iostream>
#include <string>
#include <string.h>
#pragma comment(lib, "ws2_32.lib")
#define ZeroMemory
using namespace std;
WSADATA wsadata;
SOCKET Client;
SOCKADDR_IN Server;
unsigned int Port = 5020;
int ret;
char buf[4096];
int len, tolen, fromlen, namelen;
int main(int argc, char * argv[])
{
// Initialize Winsocket
ret = WSAStartup(MAKEWORD(2, 2), &wsadata);
// CHECKS THE SOCKET STATUS
if (ret == SOCKET_ERROR)
{
printf("Client: Winstock Status is: %s ", wsadata.szSystemStatus);
WSACleanup();
cout << endl;
}
else
{
printf("Client: Winstock Status is: %s ", wsadata.szSystemStatus);
cout << endl;
}
// Client Address
Server.sin_family = AF_INET;
Server.sin_port = htons(Port);
inet_pton(AF_INET, "127.0.0.1", &Server.sin_addr);
// Create Socket
ret = Client = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
// CHECKS IF SOCKET IS CREATED
if (Client == INVALID_SOCKET)
{
cout << "Client: Can't Create Socket! ERROR: %s " << WSAGetLastError();
WSACleanup();
cout << endl;
}
// Bind Socket
ret = bind(Client, (sockaddr*)& Server,sizeof(Server));
// CHECKS IF SOCKET IS BINDED
if (ret == INVALID_SOCKET)
{
cout << "Client: Failed to bind socket" << WSAGetLastError(); ;
cout << endl;
}
string s(argv[1]);
// SendTo()
ret = sendto
(
Client,
s.c_str(),
s.size() + 1,
0,
(sockaddr*) & Server,
sizeof(Server)
);
if (ret == SOCKET_ERROR);
{
cout << "That did not work! Error Code: " << WSAGetLastError();
cout << endl;
}
// CloseSocket
closesocket(Client);
// CleanUp Winsocket
WSACleanup();
return 0;
}
UDP Server:
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#include <Winsock2.h>
#include <ws2tcpip.h>
#include <stdio.h>
#include <iostream>
#include <string>
#include <string.h>
#pragma comment(lib, "ws2_32.lib")
using namespace std;
WSADATA wsadata;
SOCKET ServerSocket;
SOCKADDR_IN ServerAddress, Client;
unsigned int Port = 5020;
char buf[4096];
int ret;
int len, tolen, fromlen, namelen;
int main()
{
// Initializing Socket
ret = WSAStartup(MAKEWORD(2, 2), &wsadata);
if (ret == SOCKET_ERROR)
{
cout << "Server: Failed to initialized socket. Error: " << wsadata.szSystemStatus;
cout << endl;
}
else
{
cout << "Server: Successfully initialized socket." << wsadata.szSystemStatus;
cout << endl;
}
// Sever Address
ServerAddress.sin_family = AF_INET;
ServerAddress.sin_port = htons(Port);
inet_pton(AF_INET, "127.0.0.1", &ServerAddress.sin_addr);
// Create Socket
ret = ServerSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (ret == -1)
{
cout << "Server: Failed to create socket. Error: " << WSAGetLastError();
cout << endl;
}
else
{
cout << "Server: Socket has been created ";
cout << endl;
}
// Bind Socket
ret = bind(ServerSocket, (sockaddr*)& ServerAddress, sizeof(ServerAddress));
if (ret == -1)
{
cout << "Server: Failed to bind socket. Error: " << WSAGetLastError();
cout << endl;
}
else
{
cout << "Server: Socket is binded to address ";
cout << endl;
}
int ClientLength = sizeof(Client);
while(true)
{
// receivefrom
ret = recvfrom
(
ServerSocket,
buf,
len,
0,
(sockaddr*)& Client,
&ClientLength
);
if (ret == SOCKET_ERROR)
{
cout << "Error receiving from client" << WSAGetLastError();
}
// display message
char ClientIP[256];
inet_ntop(AF_INET, &Client.sin_addr, ClientIP, 256);
cout << "message recieve from: " << ClientIP << " : " << buf << endl;
}
// Close Socket
closesocket(ServerSocket);
// Cleanup Winsocket
WSACleanup();
return 0;
}
I have executed the client first, no issues, executed server then client that's when it showed the issue.
// SendTo()
ret = sendto
(
Client,
s.c_str(),
s.size() + 1,
0,
(sockaddr*) & Server,
sizeof(Server)
);
if (ret == SOCKET_ERROR);
{
cout << "That did not work! Error Code: " << WSAGetLastError();
cout << endl;
}
Two mistakes:
ret = Client = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
If you are writing a UDP client, you need to create a UDP socket, not a TCP socket:
ret = Client = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
ret = bind(Client, (sockaddr*)& Server,sizeof(Server));
This is on the client side. Why are you trying to bind() to the server's endpoint? You use bind() to set the local address of the socket, not the remote address. Use connect() for the remote address (which you don't need to do when using sendto()).
Related
I am trying to implement a TCP server using c++. I am using Ubuntu on my system.
My Code:
#include <iostream>
#include <sys/types.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <string.h>
#include <string>
using namespace std;
int tcpip_server ()
{
cout << "Test1";
// Create a socket
int listening = socket(AF_INET, SOCK_STREAM, 0);
if (listening == -1)
{
cerr << "Can't create a socket! Quitting" << endl;
return -1;
}
// Bind the ip address and port to a socket
sockaddr_in hint;
hint.sin_family = AF_INET;
hint.sin_port = htons(54000);
inet_pton(AF_INET, "0.0.0.0", &hint.sin_addr);
bind(listening, (sockaddr*)&hint, sizeof(hint));
// Tell Winsock the socket is for listening
listen(listening, SOMAXCONN);
// Wait for a connection
sockaddr_in client;
socklen_t clientSize = sizeof(client);
int clientSocket = accept(listening, (sockaddr*)&client, &clientSize);
char host[NI_MAXHOST]; // Client's remote name
char service[NI_MAXSERV]; // Service (i.e. port) the client is connect on
memset(host, 0, NI_MAXHOST); // same as memset(host, 0, NI_MAXHOST);
memset(service, 0, NI_MAXSERV);
if (getnameinfo((sockaddr*)&client, sizeof(client), host, NI_MAXHOST, service,
NI_MAXSERV, 0) == 0)
{
cout << host << " connected on port " << service << endl;
}
else
{
inet_ntop(AF_INET, &client.sin_addr, host, NI_MAXHOST);
cout << host << " connected on port " << ntohs(client.sin_port) << endl;
}
// Close listening socket
close(listening);
// While loop: accept and echo message back to client
char buf[4096];
while (true)
{
cout << "Test2";
memset(buf, 0, 4096);
// Wait for client to send data
int bytesReceived = recv(clientSocket, buf, 4096, 0);
if (bytesReceived == -1)
{
cerr << "Error in recv(). Quitting" << endl;
break;
}
if (bytesReceived == 0)
{
cout << "Client disconnected " << endl;
break;
}
cout << string(buf, 0, bytesReceived) << endl;
// Echo message back to client
send(clientSocket, buf, bytesReceived + 1, 0);
}
// Close the socket
close(clientSocket);
return 0;
}
I know that the code gets called because when the function has a basic cout message in it, the code inside it will run. The code also compiles and runs with no errors or warnings.
But when I run the server code nothing happens and my terminal just stays blank, even the Test1 and Test2 cout messages do not print to the console. What am I doing wrong?
I'm trying to construct a simple UDP network program in C++ to establish a real-time data communication platform between two computers in my company.
The below code is for Server (receiver), and I successfully tested the network self-communication (IP='127.0.0.1').
However, if I change the IP number corresponding to another computer (147.47.42.50), I face a binding failure error.
When I type 'ping' in cmd, it successfully returns responses.
Is there any incorrect logic in my program? and is there any way to debug this problem?
#include <stdio.h>
#include <iostream>
#include <winsock2.h>
#include <windows.h>
#pragma comment (lib,"ws2_32.lib")
#define BUFFER_SIZE 1024
using namespace std;
void main(void)
{
WSADATA wsaData;
SOCKET ServerSocket;
SOCKADDR_IN ServerInfo;
SOCKADDR_IN FromClient;
int FromClient_Size;
int Recv_Size;
int Send_Size;
int Count;
char Buffer[BUFFER_SIZE];
short ServerPort = 6000;
if (WSAStartup(0x202, &wsaData) == SOCKET_ERROR)
{
cout << "WinSock initialization fail. " << endl;
WSACleanup();
}
memset(&ServerInfo, 0, sizeof(ServerInfo));
memset(&FromClient, 0, sizeof(FromClient));
memset(Buffer, 0, BUFFER_SIZE);
ServerInfo.sin_family = AF_INET;
ServerInfo.sin_addr.s_addr = inet_addr("147.47.42.50");
ServerInfo.sin_port = htons(ServerPort);
ServerSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (ServerSocket == INVALID_SOCKET) //
{
cout << "Cannot create socket." << endl;
closesocket(ServerSocket);
WSACleanup();
exit(0);
}
if (bind(ServerSocket, (struct sockaddr*)&ServerInfo,
sizeof(struct sockaddr)) == SOCKET_ERROR)
{
cout << "Bind fail." << endl;
closesocket(ServerSocket);
WSACleanup();
exit(0);
}
while (1)
{
FromClient_Size = sizeof(FromClient);
Recv_Size = recvfrom(ServerSocket, Buffer, BUFFER_SIZE, 0,
(struct sockaddr*)&FromClient, &FromClient_Size);
if (Recv_Size < 0)
{
cout << "recvfrom() error!" << endl;
exit(0);
}
cout << "Receive! client IP: " << inet_ntoa(FromClient.sin_addr) << endl;
cout << "Data: " << Buffer << endl;
}
closesocket(ServerSocket);
WSACleanup();
}
I am writing a code of Image file transfer using socket programming.
Here, client is sending one request message to server for some file to send to client. After receiving message from client, server is sending text file to client.
But now I need to modify this to receive Image file instead of text file.
Please help me to solve the code for image transfer.
Here is the Server and Client code
//**server**
#define _CRT_SECURE_NO_DEPRECATE
#include <iostream>
#include <WS2tcpip.h>
#include <string>
#define SIZE 10241
#pragma comment (lib, "ws2_32.lib")
using namespace std;
void send_file(FILE* fp, int clientSocket) {
//int n;
char data[SIZE] = { 0 };
while (fgets(data, SIZE, fp) != NULL) {
if (send(clientSocket, data, sizeof(data), 0) == -1) {
perror("[-]Error in sending file.");
exit(1);
}
//bzero(data, SIZE);
//memset((data), '\0', (SIZE)), (void)0);
}
}
void main()
{
// Initialze winsock
WSADATA wsData;
WORD ver = MAKEWORD(2, 2);
int wsOk = WSAStartup(ver, &wsData);
if (wsOk != 0)
{
cerr << "Can't Initialize winsock! Quitting" << endl;
return;
}
// Create a socket
SOCKET listening = socket(AF_INET, SOCK_STREAM, 0);
if (listening == INVALID_SOCKET)
{
cerr << "Can't create a socket! Quitting" << endl;
return;
}
else
{
printf("socket created \n");
}
// Bind the ip address and port to a socket
sockaddr_in hint;
hint.sin_family = AF_INET;
hint.sin_port = htons(54000);
hint.sin_addr.S_un.S_addr = INADDR_ANY; // Could also use inet_pton ....
bind(listening, (sockaddr*)&hint, sizeof(hint));
// Tell Winsock the socket is for listening
//listen(listening, SOMAXCONN);
if (listen(listening, SOMAXCONN) == SOCKET_ERROR) {
printf("Listen failed with error: %ld\n", WSAGetLastError());
}
else {
printf("listening...\n");
}
// Wait for a connection
sockaddr_in client;
int clientSize = sizeof(client);
SOCKET clientSocket = accept(listening, (sockaddr*)&client, &clientSize);
char host[NI_MAXHOST]; // Client's remote name
char service[NI_MAXSERV]; // Service (i.e. port) the client is connect on
ZeroMemory(host, NI_MAXHOST); // same as memset(host, 0, NI_MAXHOST);
ZeroMemory(service, NI_MAXSERV);
if (getnameinfo((sockaddr*)&client, sizeof(client), host, NI_MAXHOST, service, NI_MAXSERV, 0) == 0)
{
cout << host << " connected on port " << service << endl;
}
else
{
inet_ntop(AF_INET, &client.sin_addr, host, NI_MAXHOST);
cout << host << " connected on port " <<
ntohs(client.sin_port) << endl;
}
FILE* fp = fopen("original.txt", "r");
// Close listening socket
//closesocket(listening);
if (fp == NULL) {
perror("[-]Error in reading file.");
exit(1);
}
// While loop: accept and echo message back to client
char buf[4096];
//while (true)
//{
ZeroMemory(buf, 4096);
// Wait for client to send data
int bytesReceived = recv(clientSocket, buf, 4096, 0);
if (bytesReceived > 0)
{
printf("Bytes received: %d\n", bytesReceived);
}
if (bytesReceived == SOCKET_ERROR)
{
//cerr << "Error in recv(). Quitting" << endl;
printf("recv failed: %d\n", WSAGetLastError());
// break;
}
if (bytesReceived == 0)
{
cout << "Client disconnected " << endl;
// break;
}
cout << string(buf, 0, bytesReceived) << endl;
// Echo message back to client
send(clientSocket, buf, bytesReceived + 1, 0);
send_file(fp, clientSocket);
printf("[+]File data sent successfully.\n");
printf("[+]Closing the connection.\n");
// Close the socket
closesocket(clientSocket);
//}
// Cleanup winsock
WSACleanup();
//system("pause");
}
//**client**
#define _CRT_SECURE_NO_DEPRECATE
#include <iostream>
#include <string>
#include <WS2tcpip.h>
#define SIZE 10241
#pragma comment(lib, "ws2_32.lib")
using namespace std;
void write_file(int sock) {
int n;
FILE* fp;
char buffer[SIZE];
fp = fopen("copy.txt", "w");
while (1) {
n = recv(sock, buffer, SIZE, 0);
if (n <= 0) {
break;
return;
}
fprintf(fp, "%s", buffer);
//(memset((buffer), '\0', (SIZE)));
}
fclose(fp);
return;
}
void main()
{
string ipAddress = "127.0.0.1"; // IP Address of the server
int port = 54000; // Listening port # on the server
// Initialize WinSock
WSAData data;
WORD ver = MAKEWORD(2, 2);
int wsResult = WSAStartup(ver, &data);
if (wsResult != 0)
{
cerr << "Can't start Winsock, Err #" << wsResult << endl;
return;
}
// Create socket
SOCKET sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock == INVALID_SOCKET)
{
cerr << "Can't create socket, Err #" << WSAGetLastError() << endl;
WSACleanup();
return;
}
// Fill in a hint structure
sockaddr_in hint;
hint.sin_family = AF_INET;
hint.sin_port = htons(port);
inet_pton(AF_INET, ipAddress.c_str(), &hint.sin_addr);
// Connect to server
int connResult = connect(sock, (sockaddr*)&hint, sizeof(hint));
if (connResult == SOCKET_ERROR)
{
cerr << "Can't connect to server, Err #" << WSAGetLastError() << endl;
closesocket(sock);
WSACleanup();
return;
}
// Do-while loop to send and receive data
//int new_sock;
//struct sockaddr_in new_addr;
//socklen_t addr_size;
//char buffer[SIZE];
//addr_size = sizeof(new_addr);
//new_sock = accept(listen_socket, (struct sockaddr*)&new_addr, &addr_size);
char buf[4096];
string userInput;
do
{
// Prompt the user for some text
cout << "Write Data : ";
getline(cin, userInput);
if (userInput.size() > 0) // Make sure the user has typed in something
{
// Send the text
int sendResult = send(sock, userInput.c_str(), userInput.size() + 1, 0);
if (sendResult != SOCKET_ERROR)
{
// Wait for response
ZeroMemory(buf, 4096);
int bytesReceived = recv(sock, buf, 4096, 0);
if (bytesReceived > 0)
{
// Echo response to console
cout << "SERVER : " << string(buf, 0, bytesReceived) << endl;
write_file(sock);
printf("Data received successfully\n");
}
}
}
break;
} while (userInput.size() > 0);
// close down everything
closesocket(sock);
WSACleanup();
}
Thanks.
I'm trying to create a server client that once its working I can pass a vector into it and send it to a client program through ssh like putty. The issue is whenever I try to connect raw or ssh with putty on 127.0.0.1:45000 the program terminates once it connects.
Here is my code:
#include <iostream>
#include <WS2tcpip.h>
#include <string>
#pragma comment (lib, "ws2_32.lib")
using namespace std;
void main()
{
// Initialize winsock
WSADATA wsData;
WORD ver = MAKEWORD(2, 2);
int wsOk = WSAStartup(ver, &wsData);
if (wsOk != 0)
{
cerr << "Can't Intitialze winsock! Quiting" << endl;
return;
}
// Create a socket to bind
SOCKET listening = socket(AF_INET, SOCK_STREAM, 0);
if (listening == INVALID_SOCKET)
{
cerr << "Can't create a socket! Quitting" << endl;
}
// Bind the socket to an ip address to the port
sockaddr_in hint;
hint.sin_family = AF_INET;
hint.sin_port = htons(45000);
hint.sin_addr.S_un.S_addr = INADDR_ANY; // could also use inet_pton
bind(listening, (sockaddr*)&hint, sizeof(hint));
// Tell winsock the socket is for listening
listen(listening, SOMAXCONN);
// Wait for connection
sockaddr_in client;
int clientSize = sizeof(client);
SOCKET clientSocket = accept(listening, (sockaddr*)&client, &clientSize);
char host[NI_MAXHOST]; //Clients remote name
char service[NI_MAXHOST]; // Service (port) the client is on
ZeroMemory(host, NI_MAXHOST);
ZeroMemory(service, NI_MAXHOST); // use mem set of linux
if (getnameinfo((sockaddr*)&client, sizeof(client), host, NI_MAXHOST, service, NI_MAXSERV, 0) == 0)
{
cout << host << " connected on port " << service << endl;
return;
}
else
{
inet_ntop(AF_INET, &client.sin_addr, host, NI_MAXHOST);
cout << host << " connected on port " <<
ntohs(client.sin_port) << endl;
return;
}
// Close listening socket
closesocket(listening);
// while loop; accept and echo message back to client
char buf[4096];
while (true)
{
ZeroMemory(buf, 4096);
// wait for client to send data
int bytesReceived = recv(clientSocket, buf, 4096, 0);
if (bytesReceived == SOCKET_ERROR)
{
cerr << "Error in recv(). Quitting" << endl;
break;
}
if (bytesReceived == 0)
{
cout << "Client Disconnected, bytes 0" << endl;
break;
}
// echo message back to client
send(clientSocket, buf, bytesReceived + 1, 0);
// Close the socket
}
closesocket(clientSocket);
// Shutdown winsock
WSACleanup();
}
I'm writing it and compiling in Visual Studio 2019.
Here's the message I get from Putty when trying to connect with the ssh option or raw.
If anyone can help it would be greatly appreciated. Thanks!
When calling getnameinfo(), you are return'ing from main() immediately, without calling closesocket() first, regardless of whether getnameinfo() is successful or fails. This is the root of your Putty error. You are explicitly exiting your app whenever a client connects, without informing the client that the connection is being closed.
More generally, if accept() is successful (and socket(), too), you should always call closesocket() on the returned SOCKET, regardless of anything else happening in your code (same with WSACleanup() if WSAStartup() is successful).
There are several other mistakes in your code:
It is illegal for main() to have a non-int return type (though some compilers allow this, as a non-standard extension. Don't rely on this!).
You are missing a return from main() if socket() fails.
You are not checking for errors on bind(), listen(), accept(), or send().
There is no point in setting the backlog to SOMAXCONN if you are only going to accept() 1 client ever.
you have a potential buffer overflow when calling send(). Imagine if recv() returned exactly 4096 bytes received. Sending bytesReceived + 1 number of bytes back to the client would go out of bounds of your buf array.
With that said, try something more like this:
#include <iostream>
#include <WS2tcpip.h>
#include <string>
#pragma comment (lib, "ws2_32.lib")
using namespace std;
int main()
{
// Initialize winsock
WSADATA wsData;
WORD ver = MAKEWORD(2, 2);
int errCode = WSAStartup(ver, &wsData);
if (errCode != 0)
{
cerr << "Can't initialize winsock! Error " << errCode << ". Quitting" << endl;
return 0;
}
// Create a socket to bind
SOCKET listening = socket(AF_INET, SOCK_STREAM, 0);
if (listening == INVALID_SOCKET)
{
errCode = WSAGetLastError();
cerr << "Can't create listening socket! Error " << errCode << ". Quitting" << endl;
WSACleanup();
return 0;
}
// Bind the socket to an ip address to the port
sockaddr_in hint = {};
hint.sin_family = AF_INET;
hint.sin_port = htons(45000);
hint.sin_addr.s_addr = INADDR_ANY; // could also use inet_pton
if (bind(listening, (sockaddr*)&hint, sizeof(hint)) == SOCKET_ERROR)
{
errCode = WSAGetLastError();
cerr << "Can't bind listening socket! Error " << errCode << ". Quitting" << endl;
closesocket(listening);
WSACleanup();
return 0;
}
// Tell winsock the socket is for listening
if (listen(listening, 1) == SOCKET_ERROR)
{
errCode = WSAGetLastError();
cerr << "Can't open listening socket! Error " << errCode << ". Quitting" << endl;
closesocket(listening);
WSACleanup();
return 0;
}
// Wait for connection
sockaddr_in client;
int clientSize = sizeof(client);
SOCKET clientSocket = accept(listening, (sockaddr*)&client, &clientSize);
if (clientSocket == INVALID_SOCKET)
{
errCode = WSAGetLastError();
cerr << "Can't accept a client! Error " << errCode << ". Quitting" << endl;
closesocket(listening);
WSACleanup();
return 0;
}
char host[NI_MAXHOST]; //Clients remote name
char service[NI_MAXHOST]; // Service (port) the client is on
ZeroMemory(host, NI_MAXHOST);
ZeroMemory(service, NI_MAXHOST); // use mem set of linux
if (getnameinfo((sockaddr*)&client, clientSize, host, NI_MAXHOST, service, NI_MAXSERV, 0) == 0)
{
cout << host << " connected on port " << service << endl;
}
else
{
inet_ntop(AF_INET, &(client.sin_addr), host, NI_MAXHOST);
cout << host << " connected on port " << ntohs(client.sin_port) << endl;
}
// Close listening socket
closesocket(listening);
listening = INVALID_SOCKET;
// while loop; accept and echo message back to client
char buf[4096];
while (true)
{
// wait for client to send data
int bytesReceived = recv(clientSocket, buf, sizeof(buf), 0);
if (bytesReceived == SOCKET_ERROR)
{
errCode = WSAGetLastError();
cerr << "Error reading from client: " << errCode << ". Quitting" << endl;
break;
}
if (bytesReceived == 0)
{
cout << "Client Disconnected" << endl;
break;
}
// echo message back to client
char *ptr = buf;
int bytesToSend = bytesReceived;
do
{
int bytesSent = send(clientSocket, ptr, bytesToSend, 0);
if (bytesSent == SOCKET_ERROR)
break;
ptr += bytesSent;
bytesToSend -= bytesSent;
}
while (bytesToSend > 0);
if (bytesToSend != 0)
{
errCode = WSAGetLastError();
cerr << "Error writing to client: " << errCode << ". Quitting" << endl;
break;
}
}
// Close the client socket
closesocket(clientSocket);
// Shutdown winsock
WSACleanup();
return 0;
}
I've just started with socket programming and I'm simply trying to let clients send data to a server over a TCP connection. The server will then forward the data to one fixed client that is simply going to display it.
I thought that this wouldn't be anything too hard. After I set up the server and the client that only displays the sent data, I created multiple clients using PuTTY to send some data to the server, and everything worked out just fine. The server forwarded the messages and the fixed client displayed it. But now that I've coded those "sending clients", I can only get one of those clients to send one single message and after that everything is "stuck". There is no error message or anything. As soon as I send a second message the console doesn't prompt me to give it a third message. I can only close the clients and that's it.
Here's the code for the clients that simply send data:
#include <iostream>
#include <string>
#include <WS2tcpip.h>
#pragma comment(lib, "ws2_32.lib")
void main()
{
std::string ipAddress = "127.0.0.1";
int port = 54000;
WSAData data;
WORD ver = MAKEWORD(2, 2);
int wsResult = WSAStartup(ver, &data);
if (wsResult != 0)
{
std::cerr << "Can't start Winsock, Err #" << wsResult << std::endl;
return;
}
SOCKET sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock == INVALID_SOCKET)
{
std::cerr << "Can't create socket, Err #" << WSAGetLastError() << std::endl;
WSACleanup();
return;
}
sockaddr_in hint;
hint.sin_family = AF_INET;
hint.sin_port = htons(port);
inet_pton(AF_INET, ipAddress.c_str(), &hint.sin_addr);
int connResult = connect(sock, (sockaddr*)&hint, sizeof(hint));
if (connResult == SOCKET_ERROR)
{
std::cerr << "Can't connect to server, Err #" << WSAGetLastError() << std::endl;
closesocket(sock);
WSACleanup();
return;
}
char buf[4096];
std::string userInput;
do
{
std::cout << "> ";
std::getline(std::cin, userInput);
if (userInput.size() > 0) {
int sendResult = send(sock, userInput.c_str(), userInput.size() + 1, 0);
if (sendResult != SOCKET_ERROR)
{
ZeroMemory(buf, 4096);
int bytesReceived = recv(sock, buf, 4096, 0);
if (bytesReceived > 0)
{
std::cout << "SERVER> " << std::string(buf, 0, bytesReceived) << std::endl;
}
}
}
} while (userInput.size() > 0);
closesocket(sock);
WSACleanup();
}
This is the code for the client that should just display what has been sent by the other clients:
#include <iostream>
#include <ws2tcpip.h>
#include <string>
#pragma comment(lib, "ws2_32.lib")
void main() {
std::string ipAddress = "127.0.0.1";
int port = 54000;
WSAData data;
WORD version = MAKEWORD(2, 2);
int wsResult = WSAStartup(version, &data);
if (wsResult != 0) {
std::cerr << "Can't start Winsock, Err #" << wsResult << std::endl;
return;
}
SOCKET sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock == INVALID_SOCKET) {
std::cerr << "Can't create socket, Err #" << WSAGetLastError() << std::endl;
}
sockaddr_in hint;
hint.sin_family = AF_INET;
hint.sin_port = htons(port);
inet_pton(AF_INET, ipAddress.c_str(), &hint.sin_addr);
int connResult = connect(sock, (sockaddr *)&hint, sizeof(hint));
if (connResult == SOCKET_ERROR) {
std::cerr << "Can't connect to server, Err #" << WSAGetLastError() << std::endl;
closesocket(sock);
WSACleanup();
return;
}
char buf[4096];
do {
ZeroMemory(buf, 4096);
int bytesReceived = recv(sock, buf, 4096, 0);
if (bytesReceived > 0) {
std::cout << "SERVER> " << std::string(buf, 0, bytesReceived) << std::endl;
}
} while (true);
closesocket(sock);
WSACleanup();
}
This is the code for the server that should be able to handle several clients:
#include <iostream>
#include <WS2tcpip.h>
#include <string>
#pragma comment (lib, "ws2_32.lib")
void main()
{
WSADATA wsData;
WORD ver = MAKEWORD(2, 2);
int wsOk = WSAStartup(ver, &wsData);
if (wsOk != 0)
{
std::cerr << "Can't Initialize winsock! Quitting" << std::endl;
return;
}
SOCKET listening = socket(AF_INET, SOCK_STREAM, 0);
if (listening == INVALID_SOCKET)
{
std::cerr << "Can't create a socket! Quitting" << std::endl;
return;
}
sockaddr_in hint;
hint.sin_family = AF_INET;
hint.sin_port = htons(54000);
hint.sin_addr.S_un.S_addr = INADDR_ANY;
bind(listening, (sockaddr*)&hint, sizeof(hint));
listen(listening, SOMAXCONN);
fd_set master;
FD_ZERO(&master);
FD_SET(listening, &master);
while (true)
{
fd_set copy = master;
int socketCount = select(0, ©, nullptr, nullptr, nullptr);
for (int i = 0; i < socketCount; i++)
{
SOCKET sock = copy.fd_array[i];
if (sock == listening)
{
SOCKET client = accept(listening, nullptr, nullptr);
FD_SET(client, &master);
std::string joinMsg = "Client joined\r\n";
send(client, joinMsg.c_str(), joinMsg.size() + 1, 0);
}
else
{
char buf[4096];
ZeroMemory(buf, 4096);
int bytesIn = recv(sock, buf, 4096, 0);
if (bytesIn <= 0)
{
closesocket(sock);
FD_CLR(sock, &master);
}
else
{
for (int i = 0; i < master.fd_count; i++)
{
SOCKET outSock = master.fd_array[i];
if (outSock != listening && outSock != sock)
{
send(outSock, buf, bytesIn, 0);
}
}
}
}
}
}
WSACleanup();
system("pause");
}
Can someone tell me what I've been missing? I've already spent two days figuring out, what is wrong here.