簡體   English   中英

Winsock客戶端和服務器通信

[英]winsock client and server communication

抱歉,我知道我過去一整天都在發布與同一主題相關的主題,但是我遇到了另一個問題。

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

我可以很好地運行服務器和客戶端,但是我只能從客戶端發送一個單詞(出於某種原因不能發送句子),該單詞會在服務器控制台上打印出來,但是一旦在服務器控制台上打印出來,它就會輸出“接收錯誤”並關閉。

您不能假設對send()的單個調用就足夠了(與recv()相同)。 您需要遍歷數據,直到發送/接收所有數據為止。

另外,您很可能不希望總是發送128個字符,而是應該發送所需的長度(並且在消息中具有終止符或帶前綴的長度)。

嘗試使用帶有std :: string和std :: getline的char text_buff替換輸入。

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

我不確定您的循環在那里,因為您似乎只是在第一次成功發送任何內容時退出而循環。

兩個問題
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)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM