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;
}
CodePudding user response:
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.