I have a program, that needs to communicate with a server through a HTTP POST request and then receive the answer from the server. The send and receive code is in a loop and should be executed as fast as possible. My problem is, that the recv()-function needs about 500ms until it finishes. The length of the answer i receive is unknown.
if (send(m_socket, buffer, strlen(buffer), 0) != strlen(buffer))
{
cout << "HTTP: Error sending:" << WSAGetLastError() << endl;
return "0";
}
const int buflen = 322;
char buffer2[buflen];
recv(m_socket, buffer2, buflen, 0);
What can i change to decrease the time of the recv()-function to a few ms?
Here's the complete code:
WSADATA wsaData;
SOCKET m_socket;
int iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult)
cout << "Error" << endl;
m_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (m_socket == INVALID_SOCKET)
cout << "Invalid Socket : " << WSAGetLastError() <<endl;
setsockopt(m_socket, IPPROTO_TCP, TCP_NODELAY, "1", 1);
sockaddr_in clientService;
clientService.sin_family = AF_INET;
inet_pton(AF_INET, "127.0.0.1", &clientService.sin_addr.s_addr);
clientService.sin_port = htons(80);
if (connect(m_socket, (SOCKADDR*)&clientService, sizeof(clientService)) == SOCKET_ERROR)
{
cout << "Connection Failure"<<WSAGetLastError()<<endl;
WSACleanup();
return 0;
}
while(alpha)
{
if (send(m_socket, buffer, strlen(buffer), 0) != strlen(buffer))
{
cout << "HTTP: Error sending:" << WSAGetLastError() << endl;
return "0";
}
const int lang = 322;
char buffer2[lang];
recv(m_socket, buffer2, lang, 0);
cout<<buffer2<<endl;
}
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 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 have been stuck on a problem for the past few days. I need to design a music streaming app in C++. However, I find it difficult to send the file name I get when reading the files from the directory. The file names are "sample.wav" and "sample1.wav" but the client receives and output just the letter S each time. Although if I manually send a string message assigned to a variable from the server, the client receives it just find. Can you point me in the right direction?
Thanks in advance.
Server Side
sockaddr_in hint;
hint.sin_family = AF_INET;
hint.sin_port = htons(54000);
hint.sin_addr.S_un.S_addr = INADDR_ANY;
// for local ip: inet_pton
bind(listening, (sockaddr*)&hint, sizeof(hint));
// max number of open connections (SOMAXCONN)
listen(listening, SOMAXCONN);
// waiting for connection
sockaddr_in client;
int clientSize = sizeof(client);
SOCKET clientSocket = accept(listening, (sockaddr*)&client, &clientSize);
SOCKET* client_ptr = &clientSocket;
char host[NI_MAXHOST];
// client's remote name
char service[NI_MAXSERV];
// the port on which the client connects
ZeroMemory(host, NI_MAXHOST);
//ZeroMemory(service, NI_MAXHOST);
// cleaning memory
sockList.push_back(&clientSocket);
if (getnameinfo((sockaddr*)&client, sizeof(client), host, NI_MAXHOST, service, NI_MAXSERV, 0) == 0)
{
for (int i = 0; i < 2; i++) {
int postList = send(clientSocket, mainList.GetSongName(i).c_str(), mainList.GetSongName(i).size() + 1,0);
}
}
else {
inet_ntop(AF_INET, &client.sin_addr, host, NI_MAXHOST);
cout << host << " connected on port " << ntohs(client.sin_port) << endl;
}
closesocket(listening);
}
Client side:
string ipAddress = "127.0.0.1";
int port = 54000;
WSAData data;
WORD ver = MAKEWORD(2, 2);
int wsResult = WSAStartup(ver, &data);
if (wsResult != 0) {
cerr << "Can't start Winsock, Err #:" << wsResult << endl;
return 0;
}
SOCKET sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock == INVALID_SOCKET) {
cerr << "Can't create socket. Err #:" << WSAGetLastError << endl;
return 0;
}
sockaddr_in hint;
hint.sin_family = AF_INET;
hint.sin_port = htons(port);
inet_pton(AF_INET, ipAddress.c_str(), &hint.sin_addr);
//hint.sin_addr.S_un.S_addr = INADDR_ANY;
int connResult = connect(sock, (sockaddr*)&hint, sizeof(hint));
bind(sock, (sockaddr*)&hint, sizeof(hint));
if (connResult == SOCKET_ERROR) {
cerr << "Can't connect to Server, Err #:" << WSAGetLastError() << endl;
closesocket(sock);
WSACleanup();
}
char buffer[4096];
string userInput;
ZeroMemory(buffer, 4096);
int msglen;
int numbytes = 0;
int welcomemsg = recv(sock, buffer, sizeof(buffer), 0);
cout << sizeof(buffer) << endl;
cout << "Server >>" << string(buffer, 0, welcomemsg) << endl;
do {
welcomemsg = recv(sock, buffer, 4096, 0);
if (welcomemsg > 0) {
cout << "Server >>" << string(buffer, 0, welcomemsg) << endl;
}
else {
cerr << "Client disconnected" << endl;
}
} while (welcomemsg > 0);
songList object constructor:
wchar_t* w_Path = (wchar_t*)malloc(strlen(filePath) * sizeof(wchar_t));
mbstowcs(w_Path, filePath, strlen(filePath) + 1);
HANDLE hFind;
WIN32_FIND_DATA data;
LPCWSTR m_Path = w_Path;
memset(&data, 0, sizeof(WIN32_FIND_DATA));
hFind = FindFirstFile(m_Path, &data);
if (hFind != INVALID_HANDLE_VALUE) {
int i = 0;
do {
printf("\n %S", data.cFileName);
songNames[i] = (char*)data.cFileName;
i++;
} while (FindNextFile(hFind, &data));
FindClose(hFind);
}
else {
cout << "No songs found in directory" << endl;
}
The problem is you're working in Unicode mode and the struct WIN32_FIND_DATA is typedefd to WIN32_FIND_DATAW, so songNames[i] = (char*)data.cFileName; reinterprets a string of wchar_t characters as single-byte characters.
Seen as multi-byte, a string of whar_t characters looks like a null-terminated string of 1 character.
As a quick-and-dirty fix, change your server project mode to multi-byte (note - there can be more errors in the code, so more fixes might be necessary to make it work).
But better yet, continue using Unicode mode and adjust the code to work with wchar_t characters instead of char. That means changing char buffer[] to wchar_t buffer[] and adjusting the size values where necessary.
Your use of the string constructor is incorrect
cout << "Server >>" << string(buffer, 0, welcomemsg) << endl;
should be
cout << "Server >>" << string(buffer, welcomemsg) << endl;
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.
//UDP receiver
int main()
{
WSAData wsaData;
SOCKET receivingSocket;
SOCKADDR_IN receiverAddr;
SOCKADDR_IN senderAddr;
int senderAddrSize = sizeof(senderAddr);
int port=51020;
char receiveBuf[1024];
int bufLength=1024;
cout << "UDP receiver\n";
//Initialize winsock
if (WSAStartup(MAKEWORD(2,2),&wsaData) != 0)
{
cout << "Failed. Error Code : " << WSAGetLastError();
exit(EXIT_FAILURE);
}
cout << "Initialised\n";`
if(receivingSocket = socket(AF_INET, SOCK_DGRAM, 0 ) == INVALID_SOCKET )
{
cout << "Could not create socket :" << WSAGetLastError();
}
cout << "Socket created.\n";
//fill up SOCKADDR_IN structure
senderAddr.sin_port = htons(port);
senderAddr.sin_family = AF_INET;
senderAddr.sin_addr.s_addr = htonl(INADDR_ANY);
//Bind information with socket
bind(receivingSocket, (SOCKADDR*)&senderAddr, sizeof(senderAddr));
while(1)
{
cout << "Waiting for message\n";
//try to receive some data, this is a blocking call
if (recvfrom(receivingSocket, receiveBuf, 1024, 0, (SOCKADDR*)&senderAddr, &senderAddrSize)) == SOCKET_ERROR))
{
cout << "recvfrom() failed with error code :" << WSAGetLastError();
exit(EXIT_FAILURE);
}
cout << receiveBuf;
}
//Close socket
closesocket(receivingSocket);
WSACleanup();
std::cin.get();
return 0;
}
//UDP server
int main()
{
WSAData wsaData;
SOCKET sendingSocket;
SOCKADDR_IN receiverAddr;
int port = 51010;
char sendBuf[1024]="Hello!!!";
int bufLength = 1024;
cout << "UDP server from book\n";
//Initialize socket
if (WSAStartup(MAKEWORD(2,2),&wsaData) != 0)
{
cout << "Failed. Error Code : " << WSAGetLastError();
exit(EXIT_FAILURE);
}
cout << "Initialised\n";
if(sendingSocket = socket(AF_INET, SOCK_DGRAM, 0) == INVALID_SOCKET)
{
cout << "Could not create socket : " << WSAGetLastError();
}
cout << "Socket created.\n";
//FIll out structure of receiverAdd
receiverAddr.sin_family = AF_INET;
receiverAddr.sin_port = htons(port);
receiverAddr.sin_addr.s_addr = inet_addr("192.168.1.100");
int test = bind(sendingSocket, (SOCKADDR*)&receiverAddr, sizeof(receiverAddr));
if( test < 0)
{
cout << "Bind failed with error code : %d" << WSAGetLastError();
exit(EXIT_FAILURE);
}
cout << "Bind is successful\n";
while(1)
{
cout << "Sending data...\n";
//Send datagram to receiver
if(sendto(sendingSocket, sendBuf, 1024, 0, (SOCKADDR*)&receiverAddr, sizeof(receiverAddr)) == SOCKET_ERROR)
{
cout << "sendto() failed with error code : " << WSAGetLastError();
exit(EXIT_FAILURE);
}
cout << "Sent";
}
//close socket
closesocket(sendingSocket);
WSACleanup();
std::cin.get();
// return 0;
}
Error 10038 is WSAENOTSOCK: The descriptor is not a socket.
You are calling socket() and assigning your SOCKET handles inside of if statements, but you are missing adequate parenthesis. They should be like this instead:
if( (receivingSocket = socket(AF_INET, SOCK_DGRAM, 0)) == INVALID_SOCKET )
if( (sendingSocket = socket(AF_INET, SOCK_DGRAM, 0)) == INVALID_SOCKET )
Personally, I hate code that performs assignments inside of if statements like this. I prefer to keep them separate. It is cleaner, less error-prone, and no less efficient from the compiler's perspective:
receivingSocket = socket(AF_INET, SOCK_DGRAM, 0);
if( receivingSocket == INVALID_SOCKET )
sendingSocket = socket(AF_INET, SOCK_DGRAM, 0);
if( sendingSocket == INVALID_SOCKET )
On a side note:
WSAStartup() does not use WSAGetLastError() for error reporting, it directly returns an error code instead. This is clearly stated in the WSAStartup() documentation.
int err = WSAStartup(MAKEWORD(2,2),&wsaData);
if (err != 0)
{
cout << "Failed. Error Code : " << err;
exit(EXIT_FAILURE);
}
your UDP receiver is not checking the return value of bind() for an error before entering the recvfrom() loop.