My code between the client and server works as expected except for the connection closing prematurely after only one message has been sent or received. I want both the client and the server to stay open to send multiple messages without having to reinitialize the connection every time. My code is below:
Server
#undef UNICODE
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
// Need to link with Ws2_32.lib
#pragma comment (lib, "Ws2_32.lib")
#define DEFAULT_BUFLEN 512
#define DEFAULT_PORT "27016"
int __cdecl main(void)
{
WSADATA wsaData;
int iResult;
SOCKET ListenSocket = INVALID_SOCKET;
SOCKET ClientSocket = INVALID_SOCKET;
struct addrinfo *result = NULL;
struct addrinfo hints;
int iSendResult;
char recvbuf[DEFAULT_BUFLEN];
int recvbuflen = DEFAULT_BUFLEN;
// Initialize Winsock
iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult != 0) {
printf("WSAStartup failed with error: %d\n", iResult);
return 1;
}
ZeroMemory(&hints, sizeof(hints));
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
hints.ai_flags = AI_PASSIVE;
// Resolve the server address and port
iResult = getaddrinfo(0, DEFAULT_PORT, &hints, &result);
if (iResult != 0) {
printf("getaddrinfo failed with error: %d\n", iResult);
WSACleanup();
return 1;
}
// Create a SOCKET for connecting to server
ListenSocket = socket(result->ai_family, result->ai_socktype, result->ai_protocol);
std::cout << "Server Starting..." << std::endl;
if (ListenSocket == INVALID_SOCKET) {
printf("socket failed with error: %ld\n", WSAGetLastError());
freeaddrinfo(result);
WSACleanup();
return 1;
}
// Setup the TCP listening socket
iResult = bind(ListenSocket, result->ai_addr, (int)result->ai_addrlen);
if (iResult == SOCKET_ERROR) {
printf("bind failed with error: %d\n", WSAGetLastError());
freeaddrinfo(result);
closesocket(ListenSocket);
WSACleanup();
return 1;
}
freeaddrinfo(result);
iResult = listen(ListenSocket, SOMAXCONN);
std::cout << "Waiting for clients..." << std::endl;
if (iResult == SOCKET_ERROR) {
printf("listen failed with error: %d\n", WSAGetLastError());
closesocket(ListenSocket);
WSACleanup();
return 1;
}
// Accept a client socket
ClientSocket = accept(ListenSocket, NULL, NULL);
if (ClientSocket == INVALID_SOCKET) {
printf("accept failed with error: %d\n", WSAGetLastError());
closesocket(ListenSocket);
WSACleanup();
return 1;
}
std::cout << "In the server loop ready to receive a command..." << std::endl;
// No longer need server socket
//closesocket(ListenSocket);
// Receive until the peer shuts down the connection
do {
iResult = recv(ClientSocket, recvbuf, recvbuflen, 0);
if (iResult > 0) {
printf("Bytes received: %d\n", iResult);
std::cout << recvbuf << std::endl;
// Echo the buffer back to the sender
iSendResult = send(ClientSocket, recvbuf, iResult, 0);
if (strcmp(recvbuf, "move") == 0) {
std::cout << "Command received: " << recvbuf << std::endl;
}
else if (strcmp(recvbuf, "stats") == 0) {
std::cout << "Command received: " << recvbuf << std::endl;
}
else if (strcmp(recvbuf, "shoot") == 0) {
std::cout << "Command received: " << recvbuf << std::endl;
}
if (iSendResult == SOCKET_ERROR) {
printf("send failed with error: %d\n", WSAGetLastError());
closesocket(ClientSocket);
WSACleanup();
return 1;
}
}
else if (iResult == 0)
printf("Connection closing...\n");
else {
printf("recv failed with error: %d\n", WSAGetLastError());
closesocket(ClientSocket);
WSACleanup();
return 1;
}
} while (iResult > 0);
// shutdown the connection since we're done
iResult = shutdown(ClientSocket, SD_SEND);
if (iResult == SOCKET_ERROR) {
printf("shutdown failed with error: %d\n", WSAGetLastError());
closesocket(ClientSocket);
WSACleanup();
return 1;
}
// cleanup
closesocket(ClientSocket);
WSACleanup();
system("PAUSE");
return 0;
}
Client
#define _CRT_SECURE_NO_WARNINGS
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sstream>
#include <iostream>
using std::string;
using std::cin;
// Need to link with Ws2_32.lib, Mswsock.lib, and Advapi32.lib
#pragma comment (lib, "Ws2_32.lib")
#pragma comment (lib, "Mswsock.lib")
#pragma comment (lib, "AdvApi32.lib")
#define DEFAULT_BUFLEN 512
#define DEFAULT_PORT "27016"
int __cdecl main(int argc, char **argv)
{
WSADATA wsaData;
SOCKET ConnectSocket = INVALID_SOCKET;
struct addrinfo *result = NULL,
*ptr = NULL,
hints;
// char *sendbuf = "this is a test"; // disallowed with /permissive- flag
//char *sendbuf = new char[strlen("this is a test")];
char recvbuf[DEFAULT_BUFLEN];
int iResult;
int recvbuflen = DEFAULT_BUFLEN;
// Validate the parameters
if (argc != 2) {
printf("usage: %s server-name\n", argv[0]);
return 1;
}
// Initialize Winsock
iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult != 0) {
printf("WSAStartup failed with error: %d\n", iResult);
return 1;
}
ZeroMemory(&hints, sizeof(hints));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
// Resolve the server address and port
iResult = getaddrinfo(argv[1], DEFAULT_PORT, &hints, &result);
if (iResult != 0) {
printf("getaddrinfo failed with error: %d\n", iResult);
WSACleanup();
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
ConnectSocket = socket(ptr->ai_family, ptr->ai_socktype,
ptr->ai_protocol);
if (ConnectSocket == INVALID_SOCKET) {
printf("socket failed with error: %ld\n", WSAGetLastError());
WSACleanup();
return 1;
}
// Connect to server.
iResult = connect(ConnectSocket, ptr->ai_addr, (int)ptr->ai_addrlen);
if (iResult == SOCKET_ERROR) {
closesocket(ConnectSocket);
ConnectSocket = INVALID_SOCKET;
continue;
}
break;
}
freeaddrinfo(result);
if (ConnectSocket == INVALID_SOCKET) {
printf("Unable to connect to server!\n");
WSACleanup();
return 1;
}
char *sendbuf = new char[DEFAULT_BUFLEN]();
std::cout << "In the client ready to send a command..." << std::endl;
cin.getline(sendbuf, DEFAULT_BUFLEN);
int size;
for (size = 0; sendbuf[size] != '\0'; size++);
std::cout << sendbuf << std::endl;
// Send an initial buffer
iResult = send(ConnectSocket, sendbuf, size, 0);
if (iResult == SOCKET_ERROR) {
printf("send failed with error: %d\n", WSAGetLastError());
closesocket(ConnectSocket);
WSACleanup();
return 1;
}
printf("Bytes Sent: %ld\n", iResult);
// shutdown the connection since no more data will be sent
iResult = shutdown(ConnectSocket, SD_SEND);
if (iResult == SOCKET_ERROR) {
printf("shutdown failed with error: %d\n", WSAGetLastError());
closesocket(ConnectSocket);
WSACleanup();
return 1;
}
std::cout << "Command sent: " << sendbuf << std::endl;
// Receive until the peer closes the connection
do {
iResult = recv(ConnectSocket, recvbuf, recvbuflen, 0);
if (iResult > 0)
printf("Bytes received: %d\n", iResult);
else if (iResult == 0)
printf("Connection closed\n");
else
printf("recv failed with error: %d\n", WSAGetLastError());
std::cout << iResult << std::endl;
} while (iResult > 0);
// cleanup
closesocket(ConnectSocket);
WSACleanup();
return 0;
}
Related
I am following this tutorial by MS to build a basic winsock application, problem is, both server and client compile OK however I am unable to make a connection since client simply disappears. I have VS 2017 15.7.5 installed with Windows 10 SDK (10.0.17134.0). Any ideas on what might be the problem??
Client code:
#include "stdafx.h"
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
using namespace std;
// Need to link with Ws2_32.lib, Mswsock.lib, and Advapi32.lib
#pragma comment (lib, "Ws2_32.lib")
#pragma comment (lib, "Mswsock.lib")
#pragma comment (lib, "AdvApi32.lib")
#define DEFAULT_BUFLEN 512
#define DEFAULT_PORT "27015"
int __cdecl main(int argc, char **argv)
{
WSADATA wsaData;
SOCKET ConnectSocket = INVALID_SOCKET;
struct addrinfo *result = NULL,
*ptr = NULL,
hints;
const char *sendbuf = "this is a test";
char recvbuf[DEFAULT_BUFLEN];
int iResult;
int recvbuflen = DEFAULT_BUFLEN;
// Validate the parameters
if (argc != 2) {
printf("usage: %s server-name\n", argv[0]);
return 1;
}
// Initialize Winsock
iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult != 0) {
printf("WSAStartup failed with error: %d\n", iResult);
return 1;
}
ZeroMemory(&hints, sizeof(hints));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
// Resolve the server address and port
iResult = getaddrinfo(argv[1], DEFAULT_PORT, &hints, &result);
if (iResult != 0) {
printf("getaddrinfo failed with error: %d\n", iResult);
WSACleanup();
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
ConnectSocket = socket(ptr->ai_family, ptr->ai_socktype,
ptr->ai_protocol);
if (ConnectSocket == INVALID_SOCKET) {
printf("socket failed with error: %ld\n", WSAGetLastError());
WSACleanup();
return 1;
}
// Connect to server.
iResult = connect(ConnectSocket, ptr->ai_addr, (int)ptr->ai_addrlen);
if (iResult == SOCKET_ERROR) {
closesocket(ConnectSocket);
ConnectSocket = INVALID_SOCKET;
continue;
}
break;
}
freeaddrinfo(result);
if (ConnectSocket == INVALID_SOCKET) {
printf("Unable to connect to server!\n");
WSACleanup();
return 1;
}
// Send an initial buffer
iResult = send(ConnectSocket, sendbuf, (int)strlen(sendbuf), 0);
if (iResult == SOCKET_ERROR) {
printf("send failed with error: %d\n", WSAGetLastError());
closesocket(ConnectSocket);
WSACleanup();
return 1;
}
printf("Bytes Sent: %ld\n", iResult);
// shutdown the connection since no more data will be sent
iResult = shutdown(ConnectSocket, SD_SEND);
if (iResult == SOCKET_ERROR) {
printf("shutdown failed with error: %d\n", WSAGetLastError());
closesocket(ConnectSocket);
WSACleanup();
return 1;
}
// Receive until the peer closes the connection
do {
iResult = recv(ConnectSocket, recvbuf, recvbuflen, 0);
if (iResult > 0)
printf("Bytes received: %d\n", iResult);
else if (iResult == 0)
printf("Connection closed\n");
else
printf("recv failed with error: %d\n", WSAGetLastError());
} while (iResult > 0);
// cleanup
closesocket(ConnectSocket);
WSACleanup();
cin.get();
return 0;
}
Server code:
#include "stdafx.h"
#undef UNICODE
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdlib.h>
#include <stdio.h>
// Need to link with Ws2_32.lib
#pragma comment (lib, "Ws2_32.lib")
// #pragma comment (lib, "Mswsock.lib")
#define DEFAULT_BUFLEN 512
#define DEFAULT_PORT "27015"
int __cdecl main(void)
{
WSADATA wsaData;
int iResult;
SOCKET ListenSocket = INVALID_SOCKET;
SOCKET ClientSocket = INVALID_SOCKET;
struct addrinfo *result = NULL;
struct addrinfo hints;
int iSendResult;
char recvbuf[DEFAULT_BUFLEN];
int recvbuflen = DEFAULT_BUFLEN;
// Initialize Winsock
iResult = WSAStartup(MAKEWORD(2, 2), & wsaData);
if (iResult != 0) {
printf("WSAStartup failed with error: %d\n", iResult);
return 1;
}
ZeroMemory(& hints, sizeof(hints));
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
hints.ai_flags = AI_PASSIVE;
// Resolve the server address and port
iResult = getaddrinfo(NULL, DEFAULT_PORT, & hints, & result);
if (iResult != 0) {
printf("getaddrinfo failed with error: %d\n", iResult);
WSACleanup();
return 1;
}
// Create a SOCKET for connecting to server
ListenSocket = socket(result->ai_family, result->ai_socktype, result->ai_protocol);
if (ListenSocket == INVALID_SOCKET) {
printf("socket failed with error: %ld\n", WSAGetLastError());
freeaddrinfo(result);
WSACleanup();
return 1;
}
// Setup the TCP listening socket
iResult = bind(ListenSocket, result->ai_addr, (int)result->ai_addrlen);
if (iResult == SOCKET_ERROR) {
printf("bind failed with error: %d\n", WSAGetLastError());
freeaddrinfo(result);
closesocket(ListenSocket);
WSACleanup();
return 1;
}
freeaddrinfo(result);
iResult = listen(ListenSocket, SOMAXCONN);
if (iResult == SOCKET_ERROR) {
printf("listen failed with error: %d\n", WSAGetLastError());
closesocket(ListenSocket);
WSACleanup();
return 1;
}
// Accept a client socket
ClientSocket = accept(ListenSocket, NULL, NULL);
if (ClientSocket == INVALID_SOCKET) {
printf("accept failed with error: %d\n", WSAGetLastError());
closesocket(ListenSocket);
WSACleanup();
return 1;
}
// No longer need server socket
closesocket(ListenSocket);
// Receive until the peer shuts down the connection
do {
iResult = recv(ClientSocket, recvbuf, recvbuflen, 0);
if (iResult > 0) {
printf("Bytes received: %d\n", iResult);
// Echo the buffer back to the sender
iSendResult = send(ClientSocket, recvbuf, iResult, 0);
if (iSendResult == SOCKET_ERROR) {
printf("send failed with error: %d\n", WSAGetLastError());
closesocket(ClientSocket);
WSACleanup();
return 1;
}
printf("Bytes sent: %d\n", iSendResult);
}
else if (iResult == 0)
printf("Connection closing...\n");
else {
printf("recv failed with error: %d\n", WSAGetLastError());
closesocket(ClientSocket);
WSACleanup();
return 1;
}
} while (iResult > 0);
// shutdown the connection since we're done
iResult = shutdown(ClientSocket, SD_SEND);
if (iResult == SOCKET_ERROR) {
printf("shutdown failed with error: %d\n", WSAGetLastError());
closesocket(ClientSocket);
WSACleanup();
return 1;
}
// cleanup
closesocket(ClientSocket);
WSACleanup();
return 0;
}
I am creating a multi threaded server which will allow for multiple clients to join. But I have recently added this code to my client:
if (CTRL_CLOSE_EVENT == true)
{
send(ConnectSocket, (char*)quit, 1, 0);
iResult = shutdown(ConnectSocket, SD_BOTH);
if (iResult == SOCKET_ERROR) {
printf("shutdown failed with error: %d\n", WSAGetLastError());
closesocket(ConnectSocket);
WSACleanup();
return 1;
}
This should send a quit message whenever the console is closed, but whenever I close the console it throws a runtime library error and makes me abort. It comes up with recv() function failed and send() function failed, which means the socket hasn't shut down correctly.
Here is my server code:
#undef UNICODE
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdlib.h>
#include <stdio.h>
#include <mutex>
#include <iostream>
#include <string>
#include "game.h"
#include <fstream>
// Need to link with Ws2_32.lib
#pragma comment (lib, "Ws2_32.lib")
// #pragma comment (lib, "Mswsock.lib")
#define DEFAULT_BUFLEN 512
#define DEFAULT_PORT "27015"
#define DEFAULT_IP "127.0.0.1 "
std::mutex MyMutex;
int ClientCount;
using namespace std;
std::ofstream outfile ("serverconfig.txt", std::ofstream::out | std::ofstream::app);
int callThread(SOCKET ClientSocket,int nCount)
{
MyMutex.lock();
char recvbuf[DEFAULT_BUFLEN];
int recvbuflen = DEFAULT_BUFLEN;
int iResult, iSendResult;
// Receive until the peer shuts down the connection
printf("thread count: %d\n", nCount);
do {
iResult = recv(ClientSocket, recvbuf, recvbuflen, 0);
if (iResult == 1)
{
cout << "Client " << nCount << " has left" << endl;
closesocket(ClientSocket);
nCount--;
}
if (iResult > 0)
{
printf("Bytes received: %d\n", iResult);
// Echo the buffer back to the sender
iSendResult = send(ClientSocket, recvbuf, iResult, 0);
if (iSendResult == SOCKET_ERROR) {
printf("send failed: %d\n", WSAGetLastError());
closesocket(ClientSocket);
WSACleanup();
return 1;
}
printf("Bytes sent: %d\n", iSendResult);
}
else if (iResult == 0)
{
nCount--;
printf("Connection closing...\n");
}
else {
printf("recv failed: %d\n", WSAGetLastError());
closesocket(ClientSocket);
WSACleanup();
return 1;
}
MyMutex.unlock();
}
while (iResult > 0);
}
int __cdecl main(void)
{
WSADATA wsaData;
int iResult;
SOCKET ListenSocket = INVALID_SOCKET;
SOCKET ClientSocket = INVALID_SOCKET;
struct addrinfo *result = NULL;
struct addrinfo hints;
int iSendResult;
ClientCount = 0;
char recvbuf[DEFAULT_BUFLEN];
int recvbuflen = DEFAULT_BUFLEN;
std::thread myThreads[100];
game game1;
string type;
string map;
int level;
int max;
int min;
//output server details to file
ofstream outfile;
outfile.open("serverconfig.txt");
outfile << DEFAULT_IP;
outfile << DEFAULT_PORT;
outfile.close();
//get start up data
/*cout << "please choose a type: 1: Deathmatch 2: Capture the flag 3: Blood Diamond" << endl;
cin >> type;
cout << "Please choose a map:" << endl;
cin >> map;
cout << "please choose a difficulty level between 1 - 3: " << endl;
cin >> level;
cout << "Please choose the max number of clients: " << endl;
cin >> max;
cout << "Please choose the min number of clients" << endl;
cin >> min; */
// Initialize Winsock
iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult != 0) {
printf("WSAStartup failed with error: %d\n", iResult);
return 1;
}
ZeroMemory(&hints, sizeof(hints));
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
hints.ai_flags = AI_PASSIVE;
// Resolve the server address and port
iResult = getaddrinfo(NULL, DEFAULT_PORT, &hints, &result);
if (iResult != 0) {
printf("getaddrinfo failed with error: %d\n", iResult);
WSACleanup();
return 1;
}
// Create a SOCKET for connecting to server
ListenSocket = socket(result->ai_family, result->ai_socktype, result->ai_protocol);
if (ListenSocket == INVALID_SOCKET) {
printf("socket failed with error: %ld\n", WSAGetLastError());
freeaddrinfo(result);
WSACleanup();
return 1;
}
// Setup the TCP listening socket
iResult = ::bind(ListenSocket, result->ai_addr, (int)result->ai_addrlen);
if (iResult == SOCKET_ERROR) {
printf("bind failed with error: %d\n", WSAGetLastError());
freeaddrinfo(result);
closesocket(ListenSocket);
WSACleanup();
return 1;
}
freeaddrinfo(result);
if (listen(ListenSocket, SOMAXCONN) == SOCKET_ERROR) {
printf("Listen failed with error: %ld\n", WSAGetLastError());
closesocket(ListenSocket);
WSACleanup();
return 1;
}
for (;;)
{
//creating a temp socket for accepting a connction
SOCKET ClientSocket;
// Accept a client socket
ClientSocket = accept(ListenSocket, NULL, NULL);
if (ClientSocket == INVALID_SOCKET) {
printf("accept failed: %d\n", WSAGetLastError());
closesocket(ListenSocket);
WSACleanup();
return 1;
}
else
{
myThreads[ClientCount] = std::thread(callThread, ClientSocket, ClientCount);
ClientCount++;
printf("normal count: %d\n", ClientCount);
if (ClientCount == 1)
{
cout << "Waiting for another Client to connect" << endl;
}
/*if (ClientCount >= 2)
{
cout << "Game" << type << "in progress" << endl;
}*/
}
}
// shutdown the connection since we're done
iResult = shutdown(ClientSocket, SD_SEND);
if (iResult == SOCKET_ERROR) {
printf("shutdown failed with error: %d\n", WSAGetLastError());
closesocket(ClientSocket);
WSACleanup();
return 1;
}
// cleanup
closesocket(ClientSocket);
WSACleanup();
system("PAUSE");
return 0;
}
And this is my client code:
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdlib.h>
#include <stdio.h>
#include <string>
// Need to link with Ws2_32.lib, Mswsock.lib, and Advapi32.lib
#pragma comment (lib, "Ws2_32.lib")
#pragma comment (lib, "Mswsock.lib")
#pragma comment (lib, "AdvApi32.lib")
#define DEFAULT_BUFLEN 512
#define DEFAULT_PORT "27015"
using namespace std;
int __cdecl main(int argc, char **argv)
{
WSADATA wsaData;
SOCKET ConnectSocket = INVALID_SOCKET;
struct addrinfo *result = NULL,
*ptr = NULL,
hints;
char *sendbuf = "this is a test";
char recvbuf[DEFAULT_BUFLEN];
int iResult;
int recvbuflen = DEFAULT_BUFLEN;
// Initialize Winsock
iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult != 0) {
printf("WSAStartup failed with error: %d\n", iResult);
return 1;
}
ZeroMemory(&hints, sizeof(hints));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
// Resolve the server address and port
iResult = getaddrinfo("127.0.0.1", DEFAULT_PORT, &hints, &result);
if (iResult != 0) {
printf("getaddrinfo failed with error: %d\n", iResult);
WSACleanup();
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
ConnectSocket = socket(ptr->ai_family, ptr->ai_socktype,
ptr->ai_protocol);
if (ConnectSocket == INVALID_SOCKET) {
printf("socket failed with error: %ld\n", WSAGetLastError());
WSACleanup();
return 1;
}
// Connect to server.
iResult = connect(ConnectSocket, ptr->ai_addr, (int)ptr->ai_addrlen);
if (iResult == SOCKET_ERROR) {
closesocket(ConnectSocket);
ConnectSocket = INVALID_SOCKET;
continue;
}
break;
}
freeaddrinfo(result);
if (ConnectSocket == INVALID_SOCKET) {
printf("Unable to connect to server!\n");
WSACleanup();
return 1;
}
// Send an initial buffer
iResult = send(ConnectSocket, sendbuf, (int)strlen(sendbuf), 0);
if (iResult == SOCKET_ERROR) {
printf("send failed with error: %d\n", WSAGetLastError());
closesocket(ConnectSocket);
WSACleanup();
return 1;
}
printf("Bytes Sent: %ld\n", iResult);
int quit = 1;
// Send and Receive until the peer closes the connection
do {
iResult = recv(ConnectSocket, recvbuf, recvbuflen, 0);
if (iResult > 0)
printf("Bytes received: %d\n", iResult);
else if (iResult == 0)
printf("Connection closed\n");
else
printf("recv failed with error: %d\n", WSAGetLastError());
if (CTRL_CLOSE_EVENT == true)
{
send(ConnectSocket, (char*)quit, 1, 0);
iResult = shutdown(ConnectSocket, SD_BOTH);
if (iResult == SOCKET_ERROR) {
printf("shutdown failed with error: %d\n", WSAGetLastError());
closesocket(ConnectSocket);
WSACleanup();
return 1;
}
}
}
while (iResult > 0);
// shutdown the connection since no more data will be sent
iResult = shutdown(ConnectSocket, SD_SEND);
if (iResult == SOCKET_ERROR) {
printf("shutdown failed with error: %d\n", WSAGetLastError());
closesocket(ConnectSocket);
WSACleanup();
return 1;
}
// cleanup
closesocket(ConnectSocket);
WSACleanup();
system("PAUSE");
return 0;
}
This code contacts a server on my computer and sends packets to it (the server/client connection is fine). After the program loops for a number of times, it crashes with a SIGSEGV segmentation fault. I can't figure how to stop the crash from happening.
I just recently started working with clients/servers, and I retrieved the code from: https://msdn.microsoft.com/en-us/library/windows/desktop/ms737591(v=vs.85).aspx
#define WIN32_LEAN_AND_MEAN
#define _WIN32_WINNT 0x501
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
#include <windows.h>
using namespace std;
#define DEFAULT_BUFLEN 512
#define DEFAULT_PORT "27015"
int __cdecl main(int argc, char **argv) {
WSADATA wsaData;
SOCKET ConnectSocket = INVALID_SOCKET;
struct addrinfo *result = NULL,
*ptr = NULL,
hints;
char *sendbuf = "this is a test";
char recvbuf[DEFAULT_BUFLEN];
int iResult;
int recvbuflen = DEFAULT_BUFLEN;
// Validate the parameters
/*if (argc != 2) {
printf("usage: %s server-name\n", argv[0]);
return 1;
}*/
// Initialize Winsock
iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
if (iResult != 0) {
printf("WSAStartup failed with error: %d\n", iResult);
return 1;
}
ZeroMemory( &hints, sizeof(hints) );
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
// Resolve the server address and port
iResult = getaddrinfo(argv[1], DEFAULT_PORT, &hints, &result);
if ( iResult != 0 ) {
printf("getaddrinfo failed with error: %d\n", iResult);
WSACleanup();
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
ConnectSocket = socket(ptr->ai_family, ptr->ai_socktype,
ptr->ai_protocol);
if (ConnectSocket == INVALID_SOCKET) {
printf("socket failed with error: %ld\n", WSAGetLastError());
WSACleanup();
return 1;
}
// Connect to server.
iResult = connect( ConnectSocket, ptr->ai_addr, (int)ptr->ai_addrlen);
if (iResult == SOCKET_ERROR) {
closesocket(ConnectSocket);
ConnectSocket = INVALID_SOCKET;
continue;
}
break;
}
freeaddrinfo(result);
if (ConnectSocket == INVALID_SOCKET) {
printf("Unable to connect to server!\n");
WSACleanup();
return 1;
}
// Send an initial buffer
iResult = send( ConnectSocket, sendbuf, (int)strlen(sendbuf), 0 );
if (iResult == SOCKET_ERROR) {
printf("send failed with error: %d\n", WSAGetLastError());
closesocket(ConnectSocket);
WSACleanup();
return 1;
}
printf("Bytes Sent: %ld\n", iResult);
// shutdown the connection since no more data will be sent
iResult = shutdown(ConnectSocket, SD_SEND);
if (iResult == SOCKET_ERROR) {
printf("shutdown failed with error: %d\n", WSAGetLastError());
closesocket(ConnectSocket);
WSACleanup();
return 1;
}
// Receive until the peer closes the connection
do {
iResult = recv(ConnectSocket, recvbuf, recvbuflen, 0);
if ( iResult > 0 )
printf("Bytes received: %d\n", iResult);
else if ( iResult == 0 )
printf("Connection closed\n");
else
printf("recv failed with error: %d\n", WSAGetLastError());
} while( iResult > 0 );
// cleanup
closesocket(ConnectSocket);
WSACleanup();
return main(argc,argv);
}
I am using the source code from the MSDN for the C++ Winsock Server & Client, on the server side I am putting most of the code in functions and am having a access violation error. My complete source is below.
Any help would be great, thanks in advance!
This is my j420s,cpp file.
#include "j420s.h"
//Source From : MSDN Winsock Server Code.
//Original Source : https ://msdn.microsoft.com/en- us/library/windows/desktop/ms737593(v=vs.85).aspx
int __cdecl main(void) {
WSADATA wsaData;
int iResult = NULL;
SOCKET ListenSocket = INVALID_SOCKET;
SOCKET ClientSocket = INVALID_SOCKET;
struct addrinfo *MySocketResult = NULL;
struct addrinfo MySocket;
int iSendResult;
char recvbuf[DEFAULT_BUFLEN];
int recvbuflen = DEFAULT_BUFLEN;
// Initialize Winsock
iResult = SocketInit(iResult, &wsaData);
if (iResult == 1){
return 1;
}
ZeroMemory(&MySocket, sizeof(MySocket));
MySocket.ai_family = AF_INET;
MySocket.ai_socktype = SOCK_STREAM;
MySocket.ai_protocol = IPPROTO_TCP;
MySocket.ai_flags = AI_PASSIVE;
// Resolve the server address and port
iResult = SocketAddrInfo(iResult, &MySocket, MySocketResult);
// Create a SOCKET for connecting to server
ListenSocket = SocketCreate(ListenSocket, MySocketResult);
if (ListenSocket == 1){
return 1;
}
// Setup the TCP listening socket
iResult = SocketBind(iResult, ListenSocket, MySocketResult);
if (iResult == 1) {
return 1;
}
iResult = SocketListen(iResult, ListenSocket, MySocketResult);
if (iResult == 1) {
return 1;
}
// Accept a client socket
ClientSocket = accept(ListenSocket, NULL, NULL);
if (ClientSocket == INVALID_SOCKET) {
printf("accept failed with error: %d\n", WSAGetLastError());
closesocket(ListenSocket);
WSACleanup();
return 1;
}
// No longer need server socket
closesocket(ListenSocket);
// Receive FOREVER!
while (1 == 1){
do {
iResult = recv(ClientSocket, recvbuf, recvbuflen, 0);
if (iResult > 0) {
printf("Bytes received: %d\n", iResult);
// Echo the buffer back to the sender
iSendResult = send(ClientSocket, recvbuf, iResult, 0);
if (iSendResult == SOCKET_ERROR) {
printf("send failed with error: %d\n", WSAGetLastError());
closesocket(ClientSocket);
WSACleanup();
return 1;
}
printf("Bytes sent: %d\n", iSendResult);
}
} while (iResult > 0);
}
// shutdown the connection since we're done
iResult = shutdown(ClientSocket, SD_SEND);
if (iResult == SOCKET_ERROR) {
printf("shutdown failed with error: %d\n", WSAGetLastError());
closesocket(ClientSocket);
WSACleanup();
return 1;
}
// cleanup
closesocket(ClientSocket);
WSACleanup();
system("pause");
return 0;
}
int SocketAddrInfo(int iResult, addrinfo* MySocket, addrinfo* MySocketResult){
iResult = getaddrinfo(NULL, DEFAULT_PORT, MySocket, &MySocketResult);
if (iResult != 0) {
printf("getaddrinfo failed with error: %d\n", iResult);
WSACleanup();
return 1;
}
return iResult;
}
// Socket initialization
int SocketInit(int iResult, WSADATA *wsaData){
iResult = WSAStartup(MAKEWORD(2, 2), wsaData);
if (iResult != 0) {
printf("WSAStartup failed with error: %d\n", iResult);
std::cout << "Server closing in 5 ";
for (int i = 4; i > 0; i--){
Sleep(1 * 1000);
cout << i << " ";
}
cout << "Server closing now!" << endl;
return 1;
}
return iResult;
}
// Socket create function to create a socket for connecting to our server.
SOCKET SocketCreate(SOCKET ListenSocket, addrinfo* MySocketResult){
ListenSocket = socket( MySocketResult->ai_family, MySocketResult- >ai_socktype, MySocketResult->ai_protocol );
if ( ListenSocket == INVALID_SOCKET ) {
printf("Socket failed with error: %ld\n", WSAGetLastError());
freeaddrinfo(MySocketResult);
WSACleanup();
std::cout << "Server closing in 5 ";
for (int i = 4; i > 0; i--){
Sleep(1 * 1000);
cout << i << " ";
}
cout << "Server closing now!" << endl;
return 1;
}
return ListenSocket;
}
// Socket bind function for binding our socket to an address for incoming connections.
int SocketBind(int iResult, SOCKET ListenSocket, addrinfo* MySocketResult) {
iResult = bind(ListenSocket, MySocketResult->ai_addr, (int)MySocketResult->ai_addrlen);
if (iResult == SOCKET_ERROR) {
printf("Bind failed with error: %d\n", WSAGetLastError());
freeaddrinfo(MySocketResult);
closesocket(ListenSocket);
WSACleanup();
std::cout << "Server closing in 5 ";
for (int i = 4; i > 0; i--){
Sleep(1 * 1000);
cout << i << " ";
}
cout << "Server closing now!" << endl;
return 1;
}
return iResult;
}
// Socket listen function to listen for incoming connections.
int SocketListen(int iResult, SOCKET ListenSocket, addrinfo* MySocketResult) {
freeaddrinfo(MySocketResult);
iResult = listen(ListenSocket, SOMAXCONN);
if (iResult == SOCKET_ERROR) {
printf("Listen failed with error: %d\n", WSAGetLastError());
closesocket(ListenSocket);
WSACleanup();
std::cout << "Server closing in 5 ";
for (int i = 4; i > 0; i--){
Sleep(1 * 1000);
cout << i << " ";
}
cout << "Server closing now!" << endl;
return 1;
}
return iResult;
}
// Socket accept connection function.
SOCKET SocketAcceptConnection(SOCKET ClientSocket, SOCKET ListenSocket) {
ClientSocket = accept(ListenSocket, NULL, NULL);
if (ClientSocket == INVALID_SOCKET) {
printf("accept failed with error: %d\n", WSAGetLastError());
closesocket(ListenSocket);
WSACleanup();
std::cout << "Server closing in 5 ";
for (int i = 4; i > 0; i--){
Sleep(1 * 1000);
cout << i << " ";
}
cout << "Server closing now!" << endl;
return 1;
}
closesocket(ListenSocket);
return 0;
}
Here is my j420s.h file.
#undef UNICODE
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
using std::cout;
using std::endl;
// Need to link with Ws2_32.lib
#pragma comment (lib, "Ws2_32.lib")
// #pragma comment (lib, "Mswsock.lib")
#define DEFAULT_BUFLEN 512
#define DEFAULT_PORT "10187"
int SocketInit(int, WSADATA*);
int SocketAddrInfo(int, addrinfo*, addrinfo*);
SOCKET SocketCreate(SOCKET, addrinfo* );
int SocketBind(int, SOCKET, addrinfo* );
int SocketListen(int, SOCKET, addrinfo* );
SOCKET SocketAcceptConnection(SOCKET, SOCKET );
The access violation is somewhere in this function:
int SocketAddrInfo(int iResult, addrinfo* MySocket, addrinfo* MySocketResult){
iResult = getaddrinfo(NULL, DEFAULT_PORT, MySocket, &MySocketResult);
if (iResult != 0) {
printf("getaddrinfo failed with error: %d\n", iResult);
WSACleanup();
return 1;
}
return iResult;
}
I call the function like so:
iResult = SocketAddrInfo(iResult, &MySocket, MySocketResult);
I believe it's something to do with my pointers...
Again, any help would be great! Thanks again!
The result from getaddrinfo() will be thrown away on returning from the function SocketAddrInfo(), and MySocketResult in function main() remains NULL.
After that, this NULL is passed to SocketCreate(), and it is dereferenced via MySocketResult. It should cause crush.
You should pass a pointer to MySocketResult to SocketAddrInfo() and have getaddrinfo() modify it.
int SocketAddrInfo(int iResult, addrinfo* MySocket, addrinfo** MySocketResult){
iResult = getaddrinfo(NULL, DEFAULT_PORT, MySocket, MySocketResult);
if (iResult != 0) {
printf("getaddrinfo failed with error: %d\n", iResult);
WSACleanup();
return 1;
}
return iResult;
}
How to call:
iResult = SocketAddrInfo(iResult, &MySocket, &MySocketResult);
i am completely new to sockets in c++. So i already checked a few topics here, but i am not able to get it going. Please also don't judge about the code, it's mostly try and error for myself. So what i am basically try to do is to save the response from this website:
http://automatica.ais.mw.tum.de/dbConnectKoordinator/index.php?msg=0,5,1
Further, i need to change the last numbers, then the answer will be different, for example
http://automatica.ais.mw.tum.de/dbConnectKoordinator/index.php?msg=1,1,5,1
I think, that my code already works, i tried www.example.com and i can save the answer and show it in the console. Also for other website i dont get an error code. But when i try websites like the one above it is not working and i get the errorcode 11001 during the function getaddrinfo. Same for the website "eu.battle.net/api/d3/profile/ArTzT-2294/hero/280061" for example.
So please, if somebody could help me out on this one, i would be very thankful.
Here is my code (as i already told, its a complete mess. for me it is only important to save the answer of the website, nothing else)
#include <iostream>
#include <WinSock2.h>
#include <Windows.h>
#include <stdio.h>
#include <WS2tcpip.h>
#pragma comment(lib, "Ws2_32.lib")
using namespace std;
#define DEFAULT_PORT "80"
#define DEFAULT_BUFLEN 512
int __cdecl main(int argc, char** argv)
{
WSADATA wsaData;
int iResult;
int iRetval;
DWORD dwRetval;
int i = 1;
char ipstringbuffer[46];
DWORD ipbufferlength = 46;
int recvbuflen = DEFAULT_BUFLEN;
char *sendbuf = "this is a test";
char recvbuf[DEFAULT_BUFLEN];
//argv[1] = "www.example.com";
//Winsock initialisieren
iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
if (iResult != 0)
{
cout << "WSAStartup failed: " << iResult;
return 1;
}//if
struct addrinfo *result = NULL,
*ptr = NULL,
hints;
struct sockaddr_in *sockaddr_ipv4;
struct sockaddr_in6 *sockaddr_ipv6;
LPSOCKADDR sockaddr_ip;
ZeroMemory( &hints, sizeof(hints) );
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
//Resolve the server address and port
iResult = getaddrinfo("www.example.com", DEFAULT_PORT, &hints, &result);
if (iResult != 0)
{
cout << "getaddrinfo failed: " << iResult;
WSACleanup();
//cin.get();
return 1;
}//if
for(ptr=result; ptr != NULL ;ptr=ptr->ai_next)
{
switch (ptr->ai_family)
{
case AF_UNSPEC:
break;
case AF_INET:
sockaddr_ipv4 = (struct sockaddr_in *)
ptr->ai_addr;
break;
case AF_INET6:
sockaddr_ipv6 = (struct sockaddr_in6 *)
ptr->ai_addr;
break;
case AF_NETBIOS:
break;
default:
break;
}
SOCKET ConnectSocket = INVALID_SOCKET;
//Attempt to connect to the first address returned by
//the call to getaddrinfo
ptr=result;
//Create a SOCKET for connecting to server
ConnectSocket = socket(ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol);
if (ConnectSocket == INVALID_SOCKET)
{
cout << "Error at socket(): WSAGetLastError()";
freeaddrinfo(result);
WSACleanup();
return 1;
}//if
//Connect to server.
iResult = connect( ConnectSocket, ptr->ai_addr, (int)ptr->ai_addrlen);
if (iResult == SOCKET_ERROR)
{
closesocket(ConnectSocket);
ConnectSocket = INVALID_SOCKET;
}//if
if (ConnectSocket == INVALID_SOCKET)
{
WSACleanup();
return 1;
}//if
// Send an initial buffer
iResult = send(ConnectSocket, sendbuf, (int) strlen(sendbuf), 0);
if (iResult == SOCKET_ERROR)
{
printf("send failed: %d\n", WSAGetLastError());
closesocket(ConnectSocket);
WSACleanup();
return 1;
}
printf("Bytes Sent: %ld\n", iResult);
// shutdown the connection for sending since no more data will be sent
// the client can still use the ConnectSocket for receiving data
iResult = shutdown(ConnectSocket, SD_SEND);
if (iResult == SOCKET_ERROR)
{
printf("shutdown failed: %d\n", WSAGetLastError());
closesocket(ConnectSocket);
WSACleanup();
return 1;
}
// Receive data until the server closes the connection
do
{
iResult = recv(ConnectSocket, recvbuf, recvbuflen, 0);
if (iResult > 0){
printf("Bytes received: %d\n", iResult);
cout << "Alles: \n" << recvbuf;
cout << "\n\nNur eins: \n" << recvbuf[0];
}
else if (iResult == 0){
printf("Connection closed\n");
}
else {
printf("recv failed: %d\n", WSAGetLastError());
}
} while (iResult > 0);
// shutdown the send half of the connection since no more data will be sent
iResult = shutdown(ConnectSocket, SD_SEND);
if (iResult == SOCKET_ERROR)
{
printf("shutdown failed: %d\n", WSAGetLastError());
closesocket(ConnectSocket);
WSACleanup();
return 1;
}
// cleanup
closesocket(ConnectSocket);
WSACleanup();
cin.get();
return 0;
}
I also tried this with the cpp-netlib but i also get an error: "lobboost_system-vc100-mt-gd-1_55.lib" can not be opened
How can I fetch data from a website inside a C++ program
Thank you very much!