Home > database >  Can't send Message from Server( C Socket)
Can't send Message from Server( C Socket)

Time:07-07

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.

  • Related