i created a server and client application in tcp using c++. the client just sends a message to the server.
in the code the server displays some information about the client in the console: ip address, port etc
i want the server to store the client's ip address because a different application is then going to access this list
so how can i store the ip address of all the clients that connect to the server?
server code:
WSADATA wsaData;
SOCKET ListeningSocket, NewConnection;
SOCKADDR_IN ServerAddr, SenderInfo; quantity
int Port = 7171;
char recvbuff[1024];
int ByteReceived, i, nlen;
ListeningSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (ListeningSocket == INVALID_SOCKET)
{
printf("Server: Error at socket, error code: %ld.\n", WSAGetLastError());
WSACleanup();
return 1;
}
ServerAddr.sin_family = AF_INET;
ServerAddr.sin_port = htons(Port);
ServerAddr.sin_addr.s_addr = htonl(INADDR_ANY);
if (bind(ListeningSocket, (SOCKADDR *)&ServerAddr, sizeof(ServerAddr)) == SOCKET_ERROR)
{
printf("Server: bind failed! Error code: %ld.\n", WSAGetLastError());
closesocket(ListeningSocket);
WSACleanup();
return 1;
}
if (listen(ListeningSocket, 5) == SOCKET_ERROR)
{
printf("Server: listen: Error listening on socket %ld.\n", WSAGetLastError());
closesocket(ListeningSocket);
WSACleanup();
return 1;
}
else
{
printf("Server: listening for connections...\n\n");
}
while(1)
{
NewConnection = SOCKET_ERROR;
while(NewConnection == SOCKET_ERROR)
{
NewConnection = accept(ListeningSocket, NULL, NULL);
printf("Server: New client got connected, ready to receive and send data...\n\n");
ByteReceived = recv(NewConnection, recvbuff, sizeof(recvbuff), 0);
if ( ByteReceived > 0 )
{
getsockname(ListeningSocket, (SOCKADDR *)&ServerAddr, (int *)sizeof(ServerAddr));
printf("Server: IP(s) used by Server: %s\n", inet_ntoa(ServerAddr.sin_addr));
printf("Server: port used by Server: %d\n\n", htons(ServerAddr.sin_port));
memset(&SenderInfo, 0, sizeof(SenderInfo));
nlen = sizeof(SenderInfo);
getpeername(NewConnection, (SOCKADDR *)&SenderInfo, &nlen);
printf("Server: IP used by Client: %s\n", inet_ntoa(SenderInfo.sin_addr));
printf("Server: Port used by Client: %d\n", htons(SenderInfo.sin_port));
printf("Server: Bytes received: %d\n", ByteReceived);
printf("Server: Message from client: \"");
for(i=0;i < ByteReceived;i++)
{
printf("%c", recvbuff[i]);
}
printf("\"");
}
else if ( ByteReceived == 0 )
{
printf("Server: Connection closed!\n");
}
else
{
printf("Server: recv failed with error code: %d\n", WSAGetLastError());
}
}
}
you can just collect inet_ntoa(SenderInfo.sin_addr) to a vector:
WSADATA wsaData;
SOCKET ListeningSocket, NewConnection;
SOCKADDR_IN ServerAddr, SenderInfo; quantity
int Port = 7171;
char recvbuff[1024];
int ByteReceived, i, nlen;
ListeningSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (ListeningSocket == INVALID_SOCKET)
{
printf("Server: Error at socket, error code: %ld.\n", WSAGetLastError());
WSACleanup();
return 1;
}
ServerAddr.sin_family = AF_INET;
ServerAddr.sin_port = htons(Port);
ServerAddr.sin_addr.s_addr = htonl(INADDR_ANY);
if (bind(ListeningSocket, (SOCKADDR *)&ServerAddr, sizeof(ServerAddr)) == SOCKET_ERROR)
{
printf("Server: bind failed! Error code: %ld.\n", WSAGetLastError());
closesocket(ListeningSocket);
WSACleanup();
return 1;
}
if (listen(ListeningSocket, 5) == SOCKET_ERROR)
{
printf("Server: listen: Error listening on socket %ld.\n", WSAGetLastError());
closesocket(ListeningSocket);
WSACleanup();
return 1;
}
else
{
printf("Server: listening for connections...\n\n");
}
std::vector<std::string> vClientIPs; // client ip string vector
while(1)
{
NewConnection = SOCKET_ERROR;
while(NewConnection == SOCKET_ERROR)
{
NewConnection = accept(ListeningSocket, NULL, NULL);
printf("Server: New client got connected, ready to receive and send data...\n\n");
ByteReceived = recv(NewConnection, recvbuff, sizeof(recvbuff), 0);
if ( ByteReceived > 0 )
{
getsockname(ListeningSocket, (SOCKADDR *)&ServerAddr, (int *)sizeof(ServerAddr));
printf("Server: IP(s) used by Server: %s\n", inet_ntoa(ServerAddr.sin_addr));
vClientIPs.push_back(std::string(inet_ntoa(ServerAddr.sin_addr))); //insert client ip
printf("Server: port used by Server: %d\n\n", htons(ServerAddr.sin_port));
memset(&SenderInfo, 0, sizeof(SenderInfo));
nlen = sizeof(SenderInfo);
getpeername(NewConnection, (SOCKADDR *)&SenderInfo, &nlen);
printf("Server: IP used by Client: %s\n", inet_ntoa(SenderInfo.sin_addr));
printf("Server: Port used by Client: %d\n", htons(SenderInfo.sin_port));
printf("Server: Bytes received: %d\n", ByteReceived);
printf("Server: Message from client: \"");
for(i=0;i < ByteReceived;i++)
{
printf("%c", recvbuff[i]);
}
printf("\"");
}
else if ( ByteReceived == 0 )
{
printf("Server: Connection closed!\n");
}
else
{
printf("Server: recv failed with error code: %d\n", WSAGetLastError());
}
}
}
WRITE_IP_SOMEWHERE(vClientIPs); // you can write this string vector to a file or database
Related
#define PORT 3000
int sock()
{
int valread;
struct sockaddr_in serv_addr;
const char* hello = "Hello from client";
char buffer[1024] = { 0 };
SOCKET sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock < 0)
{
printf("\n Socket creation error \n");
return -1;
}
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(PORT);
// Convert IPv4 and IPv6 addresses from text to binary form
if (inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr) <= 0)
{
printf("\nInvalid address/ Address not supported \n");
return -1;
}
if (connect(sock, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) < 0)
{
printf("\nConnection Failed \n");
return -1;
}
send(sock, hello, strlen(hello), 0);
printf("Hello message sent\n");
return 0;
}
I have this code for the sockets, to be sent at localhost:3000 address. But they are not sent, and Connection failed error pops up. I have node.js server listener socket open at that port.
On Windows only 1, you must call WSAStartup() to initialize the Winsock library before using any other socket functions, like connect(). See Initializing Winsock. And you should call WSACleanup() when you are done using Winsock.
1: On non-Windows platforms, there are no equivalent startup/cleanup functions that need to be called when using sockets.
Try something more like this:
#include <winsock2.h>
#include <windows.h>
#include <stdio.h>
#define PORT 3000
int main()
{
WSADATA wsa;
int iResult = WSAStartup(MAKEWORD(2,0), &wsa);
if (iResult != 0)
{
printf("WSAStartup failed: %d\n", iResult);
return INVALID_SOCKET;
}
printf("Winsock initialized\n");
struct sockaddr_in serv_addr;
ZeroMemory(&serv_addr, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(PORT);
// Convert IPv4 and IPv6 addresses from text to binary form
if (inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr) <= 0)
{
printf("Invalid address/ Address not supported \n");
WSACleanup();
return -1;
}
SOCKET sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (sock == INVALID_SOCKET)
{
printf("Socket creation failed: %d\n", WSAGetLastError());
WSACleanup();
return -1;
}
if (connect(sock, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) == SOCKET_ERROR)
{
printf("Connection failed: %d\n", WSAGetLastError());
closesocket(sock);
WSACleanup();
return -1;
}
printf("Connection successful\n");
const char* hello = "Hello from client";
if (send(sock, hello, strlen(hello), 0) == SOCKET_ERROR)
{
printf("Send failed: %d\n", WSAGetLastError());
closesocket(sock);
WSACleanup();
return -1;
}
printf("Hello message sent\n");
closesocket(sock);
WSACleanup();
return 0;
}
That said, you really should be using getaddrinfo() instead of inet_pton(), especially if you want to support both IPv4 and IPv6, eg:
#include <winsock2.h>
#include <ws2tcpip.h>
#include <windows.h>
#include <stdio.h>
#define PORT "3000"
int main()
{
WSADATA wsa;
int iResult = WSAStartup(MAKEWORD(2,0), &wsa);
if (iResult != 0)
{
printf("WSAStartup failed: %d\n", iResult);
return INVALID_SOCKET;
}
printf("Winsock initialized\n");
struct addrinfo hints, *addrs;
ZeroMemory(&hints, sizeof(hints));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
// Convert IPv4 and IPv6 addresses from text to binary form
iResult = getaddrinfo("127.0.0.1", PORT, &hints, &addrs);
if (iResult != 0)
{
printf("Get Address Info failed: (%d) %s\n", iResult, gai_strerror(iResult));
WSACleanup();
return -1;
}
SOCKET sock = INVALID_SOCKET;
for(struct addrinfo *addr = addrs; addr != NULL; addr = addr->ai_next)
{
sock = socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol);
if (sock != INVALID_SOCKET)
{
if (connect(sock, addr->ai_addr, addr->ai_addrlen) != SOCKET_ERROR)
break;
closesocket(sock);
sock = INVALID_SOCKET;
}
}
if (sock == INVALID_SOCKET)
{
printf("Socket creation failed/Connection failed\n");
WSACleanup();
return -1;
}
printf("Connection successful\n");
const char* hello = "Hello from client";
if (send(sock, hello, strlen(hello), 0) == SOCKET_ERROR)
{
printf("Send failed: %d\n", WSAGetLastError());
closesocket(sock);
WSACleanup();
return -1;
}
printf("Hello message sent\n");
closesocket(sock);
WSACleanup();
return 0;
}
I've been doing the Winsock tutorials and following it exactly. I can't seem to get either send() or recv() to function properly. I have a basic Server and Client program set up, and the connection is being made, but the Server isn't sending a message to the Client. Using the Telnet client also doesn't receive a response from the server. I'm not really sure what's happening, and all the questions I looked at were not basic or had stuff I couldn't really understand what they were doing.
Server.cpp
#include<WinSock2.h>
#include <io.h>
#include <stdio.h>
#pragma comment(lib, "ws2_32.lib") //winsock library
int main(int argc, char *argv[])
{
WSADATA wsa;
SOCKET s, new_socket;
sockaddr_in server, client;
int c;
char *message;
printf("\nInitialising Winsock...");
if (WSAStartup(MAKEWORD(2,2), &wsa) != 0)
{
printf("Failed. Error Code : %d", WSAGetLastError());
return 1;
}
else
printf("Initialised.\n");
//create a socket
if((s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET)
{
printf("Could not create socket : %d", WSAGetLastError());
return 2;
}
else
printf("Socket created.\n");
//prepare the sockaddr_in structure
server.sin_family = AF_INET;
server.sin_addr.S_un.S_addr = INADDR_ANY;
server.sin_port = htons(8888);
//bind the socket
if (bind(s, (sockaddr *)&server, sizeof(server)) == SOCKET_ERROR)
{
printf("Bind failed with error code : &d", WSAGetLastError());
return 3;
}
else
puts("Bind done");
//listen
listen(s, 3);
//accept an incoming connection
puts("Waiting for incoming connections...");
c = sizeof(sockaddr_in);
while (new_socket = accept(s, (sockaddr *)&client, &c) != INVALID_SOCKET)
{
printf("Connect successful...\n");
//reply to the client
message = "Hello Client, I have recieved your connection, but I have to go now, bye!\n";
send(new_socket, message, strlen(message), 0);
puts("Message sent.\n");
}
if (new_socket == INVALID_SOCKET)
{
printf("accept() failed with error code : %d", WSAGetLastError());
return 4;
}
//close the socket
closesocket(s);
WSACleanup();
return 0;
}
Client.cpp
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#include <Windows.h>
#include <WinSock2.h>
#include <WS2tcpip.h>
#include <IPHlpApi.h>
#include <stdio.h>
#pragma comment(lib, "Ws2_32.lib")
int main(int argc, char *argv[])
{
//intialize variables
WSADATA wsa;
char ip[100] = "192.168.1.117";
SOCKET s;
sockaddr_in server;
char *message, server_reply[75];
int recv_size;
//initialize Winsock
printf("\nInitialising Winsock...\n");
if(WSAStartup(MAKEWORD(2,2), &wsa) != 0)
{
printf("Failed. Error Code : %d", WSAGetLastError());
return 1;
}
printf("Initialised.\n");
//create the socket
if((s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET)
{
printf("Could not create socket : %d", WSAGetLastError());
return 3;
}
printf("Socket created.\n");
server.sin_addr.S_un.S_addr = inet_addr(ip);
server.sin_family = AF_INET;
server.sin_port = htons(8888);
//connect to the server
if (connect(s, (sockaddr *)&server, sizeof(server)) < 0)
{
puts("connect error");
return 4;
}
else
{
printf("Connect successful");
recv_size = recv(s, server_reply, 75, 0);
}
if (recv_size <= 0)
{
puts("recv() failed\n");
}
else
{
//add a NULL terminating character to make it a proper string before printing
server_reply[recv_size] = '\0';
puts(server_reply);
}
getchar();
//close the socket
closesocket(s);
WSACleanup();
return 0;
}
The client also fails to print the "recv() failed" line; it's like it's stuck at the recv() call.
On the server side:
you are not checking the return value of listen() for error.
you are not resetting c on each call to accept(), and you are not calling closesocket() on each client that is accepted.
you are not checking the return value of send() for error.
Try this instead:
#include <WinSock2.h>
#include <stdio.h>
#pragma comment(lib, "ws2_32.lib") //winsock library
int main(int argc, char *argv[])
{
WSADATA wsa;
SOCKET s, new_socket;
sockaddr_in server, client;
int c, res, messagelen;
const char *message;
printf("\nInitializing Winsock...");
res = WSAStartup(MAKEWORD(2,2), &wsa);
if (res != 0)
{
printf("Failed. Error: %d\n", res);
return 1;
}
printf("Initialized.\n");
//create a socket
if((s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET)
{
printf("Could not create socket. Error: %d\n", WSAGetLastError());
return 2;
}
printf("Socket created.\n");
//prepare the sockaddr_in structure
server.sin_family = AF_INET;
server.sin_addr.S_un.S_addr = INADDR_ANY;
server.sin_port = htons(8888);
//bind the socket
if (bind(s, (sockaddr *)&server, sizeof(server)) == SOCKET_ERROR)
{
printf("Bind failed. Error: &d", WSAGetLastError());
return 3;
}
printf("Bind done.\n");
//listen
if (listen(s, 3) == SOCKET_ERROR)
{
printf("Listen failed. Error: &d", WSAGetLastError());
return 4;
}
printf("Listening.\n");
//accept incoming connections
printf("Waiting for incoming connections...\n");
do
{
c = sizeof(sockaddr_in);
new_socket = accept(s, (sockaddr *)&client, &c);
if (new_socket == INVALID_SOCKET)
{
printf("Failed to accept a client. Error: %d\n", WSAGetLastError());
return 5;
}
printf("Client connected...\n");
//reply to the client
message = "Hello Client, I have received your connection, but I have to go now, bye!\n";
messagelen = strlen(message);
do
{
res = send(new_socket, message, messagelen, 0);
if (res == SOCKET_ERROR)
{
printf("Failed to send message. Error: %d\n", WSAGetLastError());
break;
}
message += res;
messagelen -= res;
}
while (messagelen > 0);
if (messagelen == 0)
printf("Message sent.\n");
//close the client socket
closesocket(new_socket);
}
while (true);
//close the server socket
closesocket(s);
WSACleanup();
return 0;
}
On the client side, the only real problem I see is your recv() call has a potential buffer overflow waiting to happen, since you ask it to read 75 bytes, and that is the exact size of your buffer. It just happens that your server is only sending 74 bytes max, but if it ever sent more, you could overflow the buffer when appending the '\0' terminator to it.
So, either:
call recv() with sizeof(server_reply)-1 as the buffer size, to give yourself room for the added terminator:
recv_size = recv(s, server_reply, sizeof(server_reply)-1, 0);
use printf() instead of puts() so you don't need to null-terminate the buffer at all when printing it to the console. You can pass recv_size as a parameter to limit the amount of text being printed:
//server_reply[recv_size] = '\0';
//puts(server_reply);
printf("%.*s", recv_size, server_reply);
From the MSDN documentation on closesocket():
Note To assure that all data is sent and received on a connection, an application should call shutdown before calling closesocket (see Graceful shutdown, linger options, and socket closure for more information). Also note, an FD_CLOSE network event is not posted after closesocket is called.
Basically the data you have sent was still pending when you closed the socket.
I made a simple socket using winsock in C++ and instead of hard coding it I wanted to be able to change it by inserting variables so it ask what ip and port you want to connect to but after you type in the ip it says "What PORT do you want to use" but then goes to the next conditional and says "Unable to connect to server: 0".
Here's my code:
#include <windows.h>
#include <winsock2.h>
#include <conio.h>
#include <stdio.h>
#include <iostream>
using namespace std;
#define SCK_VERSION2 0x0202
#define DEFAULT_BUFLEN 512
#define DEFAULT_PORT 27015
int main() {
//----------------------
// Declare and initialize variables.
WSADATA wsaData;
int iResult;
SOCKET ConnectSocket = INVALID_SOCKET;
struct sockaddr_in clientService;
char name[500] = "";
char ipADDRESS[500] = "";
char sPORT[500] = "";
sockaddr_in sName;
int sNameSize = sizeof(sName);
char *sendbuf = "Test";
char recvbuf[DEFAULT_BUFLEN];
int recvbuflen = DEFAULT_BUFLEN;
int WSAERROR = WSAGetLastError();
//----------------------
// Initialize Winsock
iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
if (iResult != NO_ERROR) {
printf("WSAStartup failed: %d\n", iResult);
return 1;
}
//----------------------
// Create a SOCKET for connecting to server
ConnectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (ConnectSocket == INVALID_SOCKET) {
printf("Error at socket(): %i\n", WSAGetLastError() );
WSACleanup();
return 1;
}
//----------------------
// The sockaddr_in structure specifies the address family,
// IP address, and port of the server to be connected to.
printf("What IP ADDRESS do you want to connect to? \n");
cin.get(ipADDRESS, sizeof(ipADDRESS));
printf("What PORT do you want to use? \n");
//cin.get(sPORT, sizeof(sPORT));
fgets(sPORT, sizeof(sPORT), stdin);
//u_short PORT;
u_short PORT = strtoul(sPORT, NULL, 0);
clientService.sin_family = AF_INET;
clientService.sin_addr.s_addr = inet_addr(ipADDRESS); //74.125.196.191
clientService.sin_port = htons(PORT);
//----------------------
// Connect to server.
iResult = connect( ConnectSocket, (SOCKADDR*) &clientService, sizeof(clientService) );
if ( iResult == SOCKET_ERROR) {
closesocket (ConnectSocket);
printf("Unable to connect to server: %i\n", WSAGetLastError());
WSACleanup();
return 1;
}
//----------------------
//Get local host name
iResult = gethostname(name, sizeof(name));
if (iResult == NO_ERROR) {
printf("Host Name: %s\n", name);
}
else if (iResult == SOCKET_ERROR) {
printf("Could not resolve host name: %i", WSAGetLastError());
}
//------------------------
//Get peer name
iResult = getpeername(ConnectSocket, (struct sockaddr*)&sName, &sNameSize);
if (iResult == NO_ERROR)
printf("Peer Name: %s\n", inet_ntoa(sName.sin_addr));
else if (iResult == SOCKET_ERROR)
printf("Could not get peer name: %i\n", WSAGetLastError());
//-------------------------
// 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;
}
else
printf("Bytes Sent: %i\n", iResult);
//-----------------------------
// shutdown 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;
}
// Receive until the peer closes the connection
do {
iResult = recv(ConnectSocket, recvbuf, recvbuflen, 0);
if ( iResult > 0 ) {
printf("Bytes received: %d\n", iResult); //printf("Bytes received: %d\n", iResult);
printf("From server: %s\n", recvbuf);
}
else if ( iResult == 0 )
printf("Connection closed\n");
else if (WSAERROR == WSAETIMEDOUT)
printf("recv failed: WSAETIMEDOUT\n");
} while( iResult > 0 );
// cleanup
closesocket(ConnectSocket);
WSACleanup();
system("PAUSE");
return 0;
}
I am working on a simple client-server application. However, after client runs, i get the message error 10038 with the recv(), in the server side. The socket number descriptor retains the same value in both client and server, thus i think there is no a socket error. Any help would be appreciated.
client:
#ifndef UNICODE
#define UNICODE
#endif
#define WIN32_LEAN_AND_MEAN
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdio.h>
// Need to link with Ws2_32.lib.
#pragma comment(lib, "ws2_32.lib")
int wmain()
{
// Initialize Winsock.
WSADATA wsaData;
int iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult != NO_ERROR) {
printf("WSAStartup() failed with error: %d\n", iResult);
return 1;
}
// Create a socket for connecting to server.
SOCKET ConnectSocket;
ConnectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (ConnectSocket == INVALID_SOCKET) {
printf("socket() failed with error: %ld\n", WSAGetLastError());
WSACleanup();
return 1;
}
printf("Socket descriptor: %d\n",ConnectSocket);
// The sockaddr_in structure specifies the address family,
// IP address, and port of the server to be connected to.
sockaddr_in Service;
memset(&Service, 0, sizeof(Service));
Service.sin_family = AF_INET;
Service.sin_addr.s_addr = inet_addr("127.0.0.1");
Service.sin_port = htons(27015);
// Connect to server.
iResult = connect(ConnectSocket, (SOCKADDR *) &Service, sizeof (Service));
if (iResult == SOCKET_ERROR) {
printf("connect() failed with error: %ld\n", WSAGetLastError());
iResult = closesocket(ConnectSocket);
if (iResult == SOCKET_ERROR)
printf("closesocket() failed with error: %ld\n", WSAGetLastError());
WSACleanup();
return 1;
}
printf("Connected to server.\n");
// Message that has to be sent.
char receiveBuffer[1000];
char message[1000];
printf("\nEnter message: ");
gets_s(message);
printf("Message you wrote is: %s\n", message);
// Send a message.
if (send(ConnectSocket, message, sizeof(message), 0) == SOCKET_ERROR)
{
printf("send() failed with error code: %d\n", WSAGetLastError());
}
printf("Message successfully sent to server.");
// Receive a message.
if (recv(ConnectSocket, receiveBuffer, 1000, 0) == SOCKET_ERROR)
{
printf("recv() failed with error code: %d\n", WSAGetLastError());
while(1);
}
printf("\nServer says:");
printf(receiveBuffer,sizeof(receiveBuffer));
while(1);
closesocket(ConnectSocket);
WSACleanup();
return 0;
}
server:
#ifndef UNICODE
#define UNICODE
#endif
#define WIN32_LEAN_AND_MEAN
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdio.h>
// Need to link with Ws2_32.lib
#pragma comment(lib, "ws2_32.lib")
int wmain()
{
// Initialize Winsock.
WSADATA wsaData;
int iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult != NO_ERROR) {
printf("WSAStartup() failed with error: %d\n", iResult);
return 1;
}
// Create a socket for connecting to client.
SOCKET ConnectSocket;
ConnectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (ConnectSocket == INVALID_SOCKET) {
printf("socket() failed with error: %ld\n", WSAGetLastError());
WSACleanup();
return 1;
}
printf("Socket descriptor: %d\n", ConnectSocket);
// The sockaddr_in structure specifies the address family,
// IP address, and port of the server to be connected to.
sockaddr_in Service;
memset(&Service, 0, sizeof(Service));
Service.sin_family = AF_INET;
Service.sin_addr.s_addr = inet_addr("127.0.0.1");
Service.sin_port = htons(27015);
//Bind.
if (bind(ConnectSocket, (struct sockaddr *)&Service, sizeof(Service)) == SOCKET_ERROR)
{
printf("Bind failed with error code: %d\n" , WSAGetLastError());
}
printf("Bind done.\n");
// Listen on the socket for a client.
if (listen(ConnectSocket, 1) == SOCKET_ERROR)
{
printf ("listen() failed with error: %ld\n", WSAGetLastError() );
closesocket(ConnectSocket);
WSACleanup();
return 1;
}
printf("listen() run successfully.\n");
// Accept a connection from a client.
SOCKET acceptSocket;
acceptSocket = accept(ConnectSocket, NULL, NULL);
if (acceptSocket == INVALID_SOCKET) {
printf("accept() failed with error: %d\n", WSAGetLastError());
closesocket(ConnectSocket);
WSACleanup();
return 1;
}
else{
printf("accept() run successfully.\n");
}
// No longer need server socket.
closesocket(ConnectSocket);
char receiveBuffer[1000];
int recv_len;
printf("\nWaiting for data...\n");
fflush(stdout);
// Receive a message.
if (recv_len = recv(ConnectSocket, receiveBuffer, 1000, 0) == SOCKET_ERROR)
{
printf("Socket descriptor, after recv(): %d\n", ConnectSocket);
printf("recv() failed with error code: %d\n", WSAGetLastError());
while(1);
}
// Send a message.
if (send(ConnectSocket, receiveBuffer, recv_len, 0) == SOCKET_ERROR)
{
printf("sendto() failed with error code: %d\n", WSAGetLastError());
while(1);
}
else
printf("\nMessage sent back to client.");
while(1);
closesocket(ConnectSocket);
WSACleanup();
return 0;
}
I am a beginner at Winsock programming and any help would be appreciated.
Error 10038 is WSAENOTSOCK, which means you do not have a valid socket. On the server side, you are using the server socket (ConnectSocket) after you have closed it. To receive and send, you need to use the connected socket (acceptSocket) instead. Also, you need to close acceptSocket when you are done with it, do not close ConnectSocket a second time.
I use following code to check if a port is available or not:
bool ClassA::CheckPortTCP(short int dwPort , char *ipAddressStr)
{
struct sockaddr_in client;
int sock;
client.sin_family = AF_INET;
client.sin_port = htons(dwPort);
client.sin_addr.S_un.S_addr = inet_addr(ipAddressStr);
sock = (int) socket(AF_INET, SOCK_STREAM, 0);
int result = connect(sock, (struct sockaddr *) &client,sizeof(client));
// change to result == 0 -> failure in writing code too quick ;-)
if (result = 0) return true; // port is active and used
else return false;
}
The problem is if the port is opened but not connected the check failed! How can I easily examine that the port is available (not listening, not connected)?
e.g. port 21111 (output of netstat) -> my function doesn't recognize that the port is not free
TCP 0.0.0.0:21111 xxxxDUMMYxxxx:0 LISTENING
Thx
You have two errors: The first is that in the if statement you assign zero to result. The other is that connect returns -1 on failure to connect, and a non-negative value if it manages to connect.
There is also a problem that if you manage to connect, you don't close that connection.
the line client.sin_addr.S_un.S_addr = inet_addr(ipAddressStr); can not work for me. change it to:
bool CheckPortTCP(short int dwPort, char *ipAddressStr)
{
WSADATA wsaData;
int iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult != NO_ERROR) {
wprintf(L"WSAStartup function failed with error: %d\n", iResult);
return false;
}
struct sockaddr_in client;
int sock;
client.sin_family = AF_INET;
client.sin_port = htons(dwPort);
client.sin_addr.s_addr = inet_addr(ipAddressStr);
sock = (int)socket(AF_INET, SOCK_STREAM, 0);
if (sock == INVALID_SOCKET) {
wprintf(L"ERROR: Socket function failed with error: %ld\n", WSAGetLastError());
WSACleanup();
return false;
}
printf("INFO: Checking Port : %s:%d\n", ipAddressStr, dwPort);
int result = connect(sock, (struct sockaddr *) &client, sizeof(client));
if (result == SOCKET_ERROR) {
printf("ERROR: %s", WSAGetLastError());
WSACleanup();
return false;
}
else
{
WSACleanup();
closesocket(sock);
return true;
}
}