Winsock клиент и сервер связи - PullRequest
1 голос
/ 22 ноября 2010

извините, я знаю, что я публиковал темы, связанные с той же темой, в течение последнего дня, но я столкнулся с другой проблемой.

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;
}

Я могу нормально запустить сервер и клиент, но я могу отправить только одно слово (не могу отправить предложение по какой-то причине) от клиента, которое выводится на консоль сервера, но как только оновыводится на консоль сервера, выводит сообщение «Ошибка приема» и закрывается.

Ответы [ 3 ]

1 голос
/ 22 ноября 2010

Вы не можете предполагать, что одного вызова на send() достаточно (и то же самое для recv()). Вам нужно перебирать данные до тех пор, пока все данные не будут отправлены / получены.

Кроме того, вы, вероятно, не хотите всегда отправлять 128 символов, вместо этого вам просто нужно отправить требуемую длину (и иметь в сообщении либо терминатор, либо префиксную длину).

0 голосов
/ 22 ноября 2010

Два выпуска
1. cin>>text_buff; читает только до первого пробела. Вы можете использовать std :: string.
2. send(sockfd,text_buff,sizeof(text_buff),0) используйте strlen(text_buff) + 1 вместо sizeof(text_buff).
Если вы используете std :: string, попробуйте

string line;  
send(sockfd, line.c_str(),line.length()+1,0)
0 голосов
/ 22 ноября 2010

Попробуйте заменить ввод с использованием char text_buff на std :: string и 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 );
}

Я не уверен насчет вашего цикла, поскольку вы, похоже, делаете цикл только для того, чтобы выйти в первый раз, когда вы успешно отправили что-либо.

...