简体   繁体   中英

winsock client and server communication

sorry I know I have been posting threads related to the same topic over throughout the past day but I've hit another issue.

server.cpp

/*Server */
#define _WIN32_WINNT 0x501
#include <iostream>
#include <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
using namespace std;

const int winsock_version = 2;
#define PORT "3490"
#define MAX_NUM_CONNECTIONS 10

int main(void){

    WSADATA wsadata;

    if (WSAStartup(MAKEWORD(winsock_version,0),&wsadata) == 0){
        cout<<"-WSAStartup Initialized." << endl;

        struct addrinfo hints,*res;
        int sock_fd;

        memset(&hints,0,sizeof hints);
        hints.ai_family = AF_UNSPEC;
        hints.ai_socktype = SOCK_STREAM;
        hints.ai_flags = AI_PASSIVE;

        if (getaddrinfo(NULL,PORT,&hints,&res) != 0){
            cout<<"-Call to getaddress was unsucceful." << endl;
        }

        if( (sock_fd = socket(res->ai_family,res->ai_socktype,res->ai_protocol)) == -1){
            cout<<"-Unable to Create socket." << endl;
        }

        if ( (bind(sock_fd, res->ai_addr, res->ai_addrlen)) != -1 ){
            cout<<"-binding successful." << endl;
        }

        if ( (listen(sock_fd,MAX_NUM_CONNECTIONS)) != -1){
            cout<<"-Listening for incoming connections." << endl;
        }
        //-------------------------------------------------------------

        struct sockaddr_storage incming_info;
        socklen_t sin_size;
        sin_size = sizeof incming_info;

        int new_fd;

        new_fd = accept(sock_fd, (struct sockaddr*)&incming_info,&sin_size);
        if (new_fd == -1){
            cout<<"-Accepting error." << endl;
        }
        if(new_fd == INVALID_SOCKET){
            cout<<"-INVALID SOCKET ERROR." << endl;
        }
        //-------------------------------------------------------------

        cout<<"Connected?" << endl;
        char buffer[128];
        while(true){
            int ret_val;

            ret_val = recv(new_fd,buffer,sizeof(buffer),0);
            if(ret_val == -1){
                cout<<"Receiving Error." << endl;
                break;
            }else if(ret_val == 0){
                cout<<"Connection has been closed!." << endl;
                break;
            }else if(ret_val > 0){
                cout<<"Server: " << buffer<< endl;
            }
        }

        cout<<"-Closing connection" << endl;
        closesocket(new_fd);
    }else{
        cout<<"-WSAStartup Initialization failed." << endl;
        if(WSACleanup()!=0){
            cout<<"-WSACleanup Successful." << endl;
        }else{
            cout<<"-WSACleanup Failed." << endl;
        }
    }
    return 0;
}

client.cpp

/*client*/
#define _WIN32_WINNT 0x501
#include <iostream>
#include <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
using namespace std;

#define PORT "3490"
#define SERVER "localhost"
const int winsockVersion = 2;


int main(void){

    WSADATA wsadata;
    if ( (WSAStartup(MAKEWORD(2,0),&wsadata)) == 0){
        cout<<"-WSAStartup Initialized." << endl;

        struct addrinfo hints, *res;
        int sockfd;

        memset(&hints,0,sizeof hints);
        hints.ai_family = AF_UNSPEC;
        hints.ai_socktype = SOCK_STREAM;

        if (getaddrinfo(SERVER,PORT,&hints,&res) != 0){
            cout<<"-getaddrinfo unsuccessful." << endl;
        }

        if ( (sockfd = socket(res->ai_family,res->ai_socktype,res->ai_protocol)) == -1 ){
            cout<<"-Unable to create socket." << endl;
        }

        if ( (connect(sockfd,res->ai_addr,res->ai_addrlen)) != -1 ){
            cout<<"-Connection Established." << endl;
        }

        cout<<"-Client connecting to: " << res->ai_addr << endl;

        while(true){
            char text_buff[128];
            cout<<"Enter text: ";
            cin>>text_buff;
            if( (send(sockfd,text_buff,sizeof(text_buff),0)) != -1 ){
                cout<<"-text_buff sent!." << endl;
                break;
            }
        closesocket(sockfd);

        }

    }else{
        cout<<"-WSAStartup Initialization failed." << endl;
        if(WSACleanup()!=0){
            cout<<"-WSACleanup Successful." << endl;
        }else{
            cout<<"-WSACleanup Failed." << endl;
        }
    }

    return 0;
}

I can run the server and client fine, but I can only send one word (cant send a sentence for some reason) from the client which gets printed out on the server console but as soon as it is printed out on the server console it outputs "Receiving error" and closes.

You can't assume that a single call to send() is enough (and the same for recv() ). You need to loop over the data until all data has been sent/received.

Also, you very probably don't want to always send 128 characters, instead you should just send the required length (and have either a terminator or a prefixed length in the message).

Try replacing the input from using a char text_buff with a std::string and std::getline.

while( true )
{
   std::string line;
   std::cout << "Enter text: ";
   std::getline( cin, line );
   if( send( sockfd, text_buff.c_str(), text_buff.size(), 0 ) ) != -1 )
   {
      std::cout << "-text_buff sent!." << std::endl;
      break;
   }
   closesocket( sockfd );
}

I am not sure about your loop there as you seem to be looping just to exit the first time you successfully send anything.

Two issues
1. cin>>text_buff; is reading only till the first space. You can use std::string.
2. send(sockfd,text_buff,sizeof(text_buff),0) use strlen(text_buff) + 1 instead of sizeof(text_buff) .
If using std::string, then try

string line;  
send(sockfd, line.c_str(),line.length()+1,0)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM