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();
}
Related
I'm new to C++ Socket and my Server can't send message to its client. The send() function return -1 always and it seems to have a problem with accpSocket. However Client can do that smoothly and I don't know what's wrong. Please help me thank you so much!
Server
#include<WinSock2.h>
#include<WS2tcpip.h>
#include<iostream>
#include<sdkddkver.h>
#include<winsock.h>
using namespace std;
int main() {
SOCKET serverSocket, acceptSocket = INVALID_SOCKET;
int port = 2403;
WSADATA wsaData;
int wsaerr;
//Step 1: Set up dll
WORD versionRequested = MAKEWORD(2, 2);
wsaerr = WSAStartup(versionRequested, &wsaData);
if (wsaerr)
cout << "The winsock dll not found";
else {
cout << "The winsock dll found\n";
cout << "Winsock dll status: " << wsaData.szSystemStatus << endl;
}
//Step 2: Set up server socket
serverSocket = INVALID_SOCKET;
serverSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (serverSocket == INVALID_SOCKET) {
cout << "Error at socket: " << WSAGetLastError();
WSACleanup();
return 0;
}
else
cout << "Server socket successfull!\n";
//Step 3: Binding socket
sockaddr_in service;
service.sin_family = AF_INET;
service.sin_addr.S_un.S_addr = INADDR_ANY;
service.sin_port = htons(port);
if (bind(serverSocket, (sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) {
cout << "Binding failed! " << WSAGetLastError();
return 0;
}
else
cout << "Binding complete!\n";
// Step 4: Listen to the connections
if (listen(serverSocket, 1) == SOCKET_ERROR) {
cout << "Listen failed! " << WSAGetLastError();
return 0;
}
else
cout << "Waiting for connections ...";
SOCKET accpSocket = accept(serverSocket, NULL, NULL);
if (accpSocket == INVALID_SOCKET) {
cout << "Accepting failed! " << WSAGetLastError();
WSACleanup();
return -1;
}
else
cout << "Accept connection!\n";
char recvMess[2000];
char sendMess[2000];
int byterecv = recv(accpSocket, recvMess, sizeof(recvMess), 0);
cout << "Client: " << recvMess << endl;
cout << "Server: ";
cin.getline(sendMess, 2000);
int bytesend = send(acceptSocket, sendMess, 2000, 0);
if (bytesend <= 0)
cout << "Unsent";
return 0;
}
Client
#include<iostream>
#include<WinSock2.h>
#include<WS2tcpip.h>
using namespace std;
int main() {
int port = 2403;
WSADATA wsaData;
int wsaerr;
SOCKET clientSocket;
WORD versionRequested = MAKEWORD(2, 2);
wsaerr = WSAStartup(versionRequested, &wsaData);
if (wsaerr)
cout << "Winsock dll not found!";
else {
cout << "Winsock dll is ok!\n";
cout << "Status: " << wsaData.szSystemStatus << endl;
}
clientSocket = INVALID_SOCKET;
clientSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (clientSocket == INVALID_SOCKET) {
cout << "Set up client socket failed" << WSAGetLastError();
WSACleanup();
return 0;
}
else
cout << "Set up complete!\n";
sockaddr_in clientService;
clientService.sin_family = AF_INET;
clientService.sin_port = htons(port);
if (inet_pton(clientService.sin_family, "127.0.0.1", &clientService.sin_addr) <= 0) {
cout << "Invalid address!";
return -1;
}
if ((connect(clientSocket, (SOCKADDR*)&clientService, sizeof(clientService))) == SOCKET_ERROR) {
cout << "Connection failed!\n";
WSACleanup();
return 0;
}
else
cout << "Connection complete!\n";
char sendMess[2000];
char recvMess[2000];
cout << "Client: ";
cin.getline(sendMess, 2000);
int bytesend = send(clientSocket, sendMess, 2000, 0);
int byterecv = recv(clientSocket, recvMess, 2000, 0);
if (byterecv <= 0)
cout << "Nothing";
else
cout << "Server" << recvMess << endl;
return 0;
}
int bytesend = send(acceptSocket, sendMess, 2000, 0);
is not sending to a connected socket. acceptSocket was defined at the top of main and then ignored up until the call to send
As a general rule of thumb, keep variable definition close to first use.
In the server at
SOCKET serverSocket, acceptSocket = INVALID_SOCKET;
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Killlllll meeeeee!!!!
remove acceptSocket to prevent future mistakes and in
int bytesend = send(acceptSocket, sendMess, 2000, 0);
replace acceptSocket with the socket that was actually accepted, accpSocket.
Side notes:
Never ignore the return codes.
int byterecv = recv(accpSocket, recvMess, sizeof(recvMess), 0);
could fail and return -1 or return 0 if the socket was disconnected, yet the program will still
cout << "Client: " << recvMess << endl;
And worse, there's no guarantee that recvMess will be null-terminated, recv on a streaming socket gives you what the socket has available or becomes available up to the maximum number of bytes requested, so if there is any data read, make sure byterecv is a valid index in recvMess by only reading sizeof(recvMess) - 1 bytes and then forcing termination with recvMess[byterecv] = '\0'; before printing.
send(acceptSocket, sendMess, 2000, 0); sends all 2000 bytes of sendMess regardless of how many bytes were read with cin.getline(sendMess, 2000);. Use
send(acceptSocket, sendMess, cin.gcount(), 0);
instead. Add on an extra byte (cin.gcount() + 1) if you want to send the null terminator.
I am writing for the first time in this language and could only write this
UDP server and client. I need help; I want to server waits for a response and displays it. If within 5 sec. the answer is not received, the program starts its execution again.If you don't understand task, you can translate task(fifth) :https://www.opennet.ru/docs/RUS/socket/node15.html
#include <iostream>
#include <WS2tcpip.h>
#pragma comment (lib, "ws2_32.lib")
using namespace std;
void main()
{
struct timeval tv;
fd_set fd;
WSADATA data;
WORD version = MAKEWORD(2, 2);
int wsOk = WSAStartup(version, &data);
cout << "Server opened" << endl;
if (wsOk != 0)
{
cout << "Can't start Winsock! " << wsOk;
return;
}
SOCKET in = socket(AF_INET, SOCK_DGRAM, 0);
sockaddr_in serverHint;
serverHint.sin_addr.S_un.S_addr = ADDR_ANY;
serverHint.sin_family = AF_INET;
serverHint.sin_port = htons(54000);
if (bind(in, (sockaddr*)& serverHint, sizeof(serverHint)) == SOCKET_ERROR)
{
cout << "Can't bind socket! " << WSAGetLastError() << endl;
return;
}
sockaddr_in client;
int clientLength = sizeof(client);
char buf[1024];
while (true)
{
FD_ZERO(&fd);
FD_SET(in, &fd);
tv.tv_sec = 5;
tv.tv_usec = 0;
if (select(0, &fd, NULL, NULL, &tv) > 0)
{
ZeroMemory(&client, clientLength);
ZeroMemory(buf, 1024);
int bytesIn = recvfrom(in, buf, 1024, 0, (sockaddr*)& client, &clientLength);
if (bytesIn == SOCKET_ERROR)
{
cout << "Error receiving from client " << WSAGetLastError() << endl;
continue;
}
char clientIp[256];
ZeroMemory(clientIp, 256);
inet_ntop(AF_INET, &client.sin_addr, clientIp, 256);
cout << "Message recv from " << clientIp << " : " << buf << endl;
}
else {
cout << "Timeout" << endl;
closesocket(in);
break;
}
closesocket(in);
WSACleanup();
}
}
Translation of the task by google translate:
Write a program that asks the user for an IP address, port number and text string,
sends a string to the specified address using the UDP protocol,
waits for a response, and displays it on the screen.
If within 5 sec. the answer is not received, the program starts its execution again.
Your program is completely missing part 1 and 2 so you must add those.
For part 3, move your current while loop so it covers everything in main:
int main() // note: main must be declared to return 'int'
{
while(true) { // new start of the while loop, first in main
// ... your current code until the below line ...
cout << "Message recv from " << clientIp << " : " << buf << endl;
// exit program if you've received a response
closesocket(in);
break; // break out of while loop
}
else {
cout << "Timeout" << endl;
}
closesocket(in);
WSACleanup();
} // end of while loop
WSACleanup();
} // end of main
This reinitializer Winsock2 for every try which is unnecessary and it also has closesocket in multiple places. I would add classes for both WSAStartup/WSACleanup and socket/closesocket to manage the resources they have acquire.
#include <iostream>
#include <WS2tcpip.h>
#pragma comment (lib, "ws2_32.lib")
using namespace std;
void main()
{
struct timeval tv;
fd_set fd;
WSADATA data;
WORD version = MAKEWORD(2, 2);
int wsOk = WSAStartup(version, &data);
cout << "5" << endl;
if (wsOk != 0)
{
cout << "Winsock" << wsOk;
return;
}
SOCKET in = socket(AF_INET, SOCK_DGRAM, 0);
sockaddr_in serverHint;
serverHint.sin_addr.S_un.S_addr = ADDR_ANY;
serverHint.sin_family = AF_INET;
serverHint.sin_port = htons(54000);
if (bind(in, (sockaddr*)& serverHint, sizeof(serverHint)) == SOCKET_ERROR)
{
cout << "hhhh" << WSAGetLastError() << endl;
return;
}
sockaddr_in client;
int clientLength = sizeof(client);
char buf[1024];
while (true)
{
FD_ZERO(&fd);
FD_SET(in, &fd);
tv.tv_sec = 5;
tv.tv_usec = 0;
if (select(0, &fd, NULL, NULL, &tv) > 0)
{
ZeroMemory(&client, clientLength);
ZeroMemory(buf, 1024);
int bytesIn = recvfrom(in, buf, 1024, 0, (sockaddr*)& client, &clientLength);
if (bytesIn == SOCKET_ERROR)
{
cout << "EEEROOR" << WSAGetLastError() << endl;
continue;
}
char clientIp[256];
ZeroMemory(clientIp, 256);
inet_ntop(AF_INET, &client.sin_addr, clientIp, 256);
cout << "ะก " << clientIp << " : " << buf << endl;
closesocket(in);
WSACleanup();
exit(0);
}
else {
cout << "jhkjhkjhjn" << endl;
closesocket(in);
main();
}
}
}
I'm studying C++, and this weekend I started to play around with sockets and threads. Bellow is a simple multi threaded server that I'm making based on some tutorials.
The issue that I'm facing is that when I'm connecting with 2 telnet clients only the keystrokes form the first connection appear on the server. Any keystroke sent from the second telnet connection appears suddenly once the first telnet connection closes. Could someone explain to me what have I done wrong here?
#include <iostream>
#include <string>
#include <thread>
#include <winsock2.h>
#include <ws2tcpip.h>
#pragma comment (lib, "ws2_32.lib")
void clientSocketHandler(SOCKET clientSocket, std::string client_ip) {
char buf[4096];
std::thread::id thread_id = std::this_thread::get_id();
std::cout << thread_id << " - " << client_ip << ": connected" << std::endl;
while (true)
{
ZeroMemory(buf, 4096);
int bytesReceived = recv(clientSocket, buf, 4096, 0);
if (bytesReceived == 0)
{
std::cout << thread_id << " - " << client_ip << ": disconnected" << std::endl;
break;
}
if (bytesReceived > 0)
{
std::cout << thread_id << " - " << client_ip << ": " << std::string(buf, 0, bytesReceived) << std::endl;
//send(clientSocket, buf, bytesReceived + 1, 0);
}
}
std::cout << thread_id << " - " << client_ip << ": closing client socket & exiting thread..." << std::endl;
closesocket(clientSocket);
}
void waitForConnections(SOCKET serverSocket) {
sockaddr_in hint;
hint.sin_family = AF_INET;
hint.sin_port = htons(1337);
hint.sin_addr.S_un.S_addr = INADDR_ANY;
bind(serverSocket, (sockaddr*)&hint, sizeof(hint));
listen(serverSocket, SOMAXCONN);
while (true) {
sockaddr_in client;
int clientSize = sizeof(client);
SOCKET clientSocket = accept(serverSocket, (sockaddr*)&client, &clientSize);
if (clientSocket != INVALID_SOCKET)
{
char host[NI_MAXHOST]; // Client's remote name
ZeroMemory(host, NI_MAXHOST); // same as memset(host, 0, NI_MAXHOST);
std::string client_ip = inet_ntop(AF_INET, &client.sin_addr, host, NI_MAXHOST);
std::thread t(clientSocketHandler, clientSocket, client_ip);
t.join();
}
Sleep(100);
}
}
int main()
{
// Initialze winsock
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 1;
}
// Create a socket
SOCKET serverSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (serverSocket == INVALID_SOCKET)
{
WSACleanup();
std::cerr << "Can't create a socket! Quitting..." << std::endl;
return 1;
}
// If serverSocketMode = 0, blocking is enabled;
// If serverSocketMode != 0, non-blocking mode is enabled.
u_long serverSocketMode = 1;
if (ioctlsocket(serverSocket, FIONBIO, &serverSocketMode) != NO_ERROR)
{
WSACleanup();
std::cerr << "Can't set socket to non-blocking mode! Quitting..." << std::endl;
return 1;
}
// Disables the Nagle algorithm for send coalescing.
// This socket option is included for backward
// compatibility with Windows Sockets 1.1
BOOL flag = TRUE;
if (setsockopt(serverSocket, IPPROTO_TCP, TCP_NODELAY, (const char *)&flag, sizeof(flag)) != NO_ERROR)
{
WSACleanup();
std::cerr << "Can't set socket NO_DELAY option! Quitting..." << std::endl;
return 1;
}
// Start listening for connections
waitForConnections(serverSocket);
// Cleanup winsock
WSACleanup();
system("pause");
return 0;
}
This should work. I removed pointless things like setting the socket to non-blocking and disabling the Nagle algorithm. The latter should only be done for things that need low-millisecond interactivity.
But, the substantial change that should fix your problem is changing join to detach. Using join causes your program to wait for the thread to finish before continuing. Using detach says "This thread is going to run in the background doing things, and I don't care about learning its fate later.".
If you don't use one of the two, and the ::std::thread object is destroyed, the system throws an exception because you're destroying the only means you have of getting information about whether or not a thread exited with an error of some kind with saying that either you don't care about such information, or explicitly asking for it.
I don't have Windows, so I can't test it:
#include <iostream>
#include <string>
#include <thread>
#include <winsock2.h>
#include <ws2tcpip.h>
#pragma comment (lib, "ws2_32.lib")
void clientSocketHandler(SOCKET clientSocket, std::string client_ip)
{
char buf[4096];
std::thread::id thread_id = std::this_thread::get_id();
std::cout << thread_id << " - " << client_ip << ": connected" << std::endl;
while (true)
{
ZeroMemory(buf, 4096);
int bytesReceived = recv(clientSocket, buf, 4096, 0);
if (bytesReceived == 0)
{
std::cout << thread_id << " - " << client_ip << ": disconnected" << std::endl;
break;
}
if (bytesReceived > 0)
{
std::cout << thread_id << " - " << client_ip << ": " << std::string(buf, 0, bytesReceived) << std::endl;
//send(clientSocket, buf, bytesReceived + 1, 0);
}
}
std::cout << thread_id << " - " << client_ip << ": closing client socket & exiting thread..." << std::endl;
closesocket(clientSocket);
}
void waitForConnections(SOCKET serverSocket)
{
sockaddr_in hint;
hint.sin_family = AF_INET;
hint.sin_port = htons(1337);
hint.sin_addr.S_un.S_addr = INADDR_ANY;
bind(serverSocket, (sockaddr*)&hint, sizeof(hint));
listen(serverSocket, SOMAXCONN);
while (true) {
sockaddr_in client;
int clientSize = sizeof(client);
SOCKET clientSocket = accept(serverSocket, (sockaddr*)&client, &clientSize);
if (clientSocket != INVALID_SOCKET)
{
char host[NI_MAXHOST]; // Client's remote name
ZeroMemory(host, NI_MAXHOST); // same as memset(host, 0, NI_MAXHOST);
std::string client_ip = inet_ntop(AF_INET, &client.sin_addr, host, NI_MAXHOST);
std::thread t(clientSocketHandler, clientSocket, client_ip);
t.detach();
}
Sleep(100);
}
}
int main()
{
// Initialze winsock
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 1;
}
// Create a socket
SOCKET serverSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (serverSocket == INVALID_SOCKET)
{
WSACleanup();
std::cerr << "Can't create a socket! Quitting..." << std::endl;
return 1;
}
// Start listening for connections
waitForConnections(serverSocket);
// Cleanup winsock
WSACleanup();
system("pause");
return 0;
}
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()).
I'd like to send a string with sockets from a client to a server.
Here's the code of the client:
#include <iostream>
#include <winsock.h>
#include <unistd.h>
using namespace std;
int main()
{
//Load socket
WSADATA wsaData;
WSAStartup(0x0202, &wsaData);
//Create first socket
int thisSocket;
struct sockaddr_in destination;
destination.sin_family = AF_INET;
thisSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (thisSocket < 0)
{
cout << "Socket Creation FAILED!" << endl;
return 0;
}
//Connect to a host
destination.sin_port = htons(13374);
destination.sin_addr.s_addr = inet_addr("127.0.0.1");
if (connect(thisSocket,(struct sockaddr *)&destination,sizeof(destination))!=0){
cout << "Socket Connection FAILED!" << endl;
if (thisSocket) close(thisSocket);
return 0;
}
cout << "Connected!" << endl;
//Send the socket
//char *buffer = "Hello, this is a socket!";
string buffer = "Hello, this is a socket!";
//send(thisSocket, buffer, (int)strlen(buffer), 0);
send(thisSocket, buffer.c_str(), buffer.length(), 0);
//Close the socket
closesocket(thisSocket);
WSACleanup();
}
And here's the code of the server:
#include <iostream>
#include <winsock.h>
#include <unistd.h>
using namespace std;
int main()
{
//Load the socket
WSADATA wsaData;
WSAStartup(0x0202, &wsaData);
//Create the first socket
int thisSocket;
struct sockaddr_in destination;
destination.sin_family = AF_INET;
thisSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (thisSocket < 0)
{
cout << "Socket Creation FAILED!" << endl;
return 0;
}
//Bind to a socket
destination.sin_port = htons (13374);
destination.sin_addr.s_addr = INADDR_ANY;
if (bind(thisSocket, (struct sockaddr *)&destination, sizeof(destination)) <0){
cout << "Binding Socket FAILED!" << endl;
if (thisSocket) close(thisSocket);
return 0;
}
//Listen on a socket
cout << "Listening on 13374..." << endl;
if (listen(thisSocket, 5)<0){
cout << "Listening on Socket FAILED!" << endl;
if (thisSocket) close(thisSocket);
return 0;
}
//Accept a connection
struct sockaddr_in clientAddress;
int clientSize = sizeof(clientAddress);
thisSocket= accept(thisSocket, (struct sockaddr *)&clientAddress, (int *) &clientSize);
if (thisSocket<0)
{
cout << "Socket Connection FAILED!" << endl;
if (thisSocket) close(thisSocket);
return 0;
}
cout <<"Connection Established!" << endl;
//Receive the socket
char buffer[512];
int newData;
newData = recv(thisSocket, buffer, 512, 0);
cout << newData << endl;
//Close the socket
closesocket(thisSocket);
WSACleanup();
}
As you can image, the server will receive the number "24".
How can I get the real string instead?
The data read by recv end up in buffer. The recv function returns how many bytes it received, zero if the connection was closed and a negative value if there was an error.
Reading a recv reference would have told you all this and more.
Do note that the data is not terminated like a string. Either terminate it as a string like
buffer[newData] = '\0';
after checking that the recv function actually received something. Or you could construct a std::string object directly:
std::string receivedString{buffer, newData};
Also don't do it unless the recv function actually received something.
Instead of:
cout << newData << endl;
do:
cout << buffer << endl;
The recv function returns the number of bytes read and the buffer holds the bytes read.