套接字编程c ++ windows,看不到从服务器接收到的消息[关闭]

Posted

技术标签:

【中文标题】套接字编程c ++ windows,看不到从服务器接收到的消息[关闭]【英文标题】:socket programming c++ windows, can't see received message from server [closed] 【发布时间】:2016-05-02 10:28:44 【问题描述】:

我正在编写一个网络客户端-服务器程序:

服务器端:

#include "stdafx.h"
#include <winsock.h>
#include <stdio.h>
#include<stdlib.h>

#define PROTOPORT 5193
#define QLEN 6
#define BUFFERSIZE 512

void ErrorHandler(char *errorMessage)

    printf(errorMessage);



void ClearWinSock()

#if defined WIN32
    WSACleanup();
#endif



int main(int argc, char *argv[])

    int port;

    if (argc > 1)
        port = atoi(argv[1]);
    else
        port = PROTOPORT;

    if (port < 0) 
        printf("Bad port number %s \n", argv[1]);
        return 0;
    

#if defined WIN32
    WSADATA wsaData;
    int iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);

    if (iResult != 0) 
        ErrorHandler("Error at WSAStartup()\n");
        return 0;
    
#endif

    //creazione della socket
    int MySocket;
    MySocket = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (MySocket < 0) 
        ErrorHandler("socket creation failed.\n");
        ClearWinSock();
        return 0;
    

    //ASSEGNAZIONE DI UN INDIRIZZO ALLA SOCKET
    struct sockaddr_in sad;
    memset(&sad, 0, sizeof(sad)); // ensures that extra bytes contain 0
    sad.sin_family = AF_INET;
    sad.sin_addr.s_addr = inet_addr("127.0.0.1");
    sad.sin_port = htons(port); /* converts values between the host and
                                network byte order. Specifically, htons() converts 16-bit quantities
                                from host byte order to network byte order. */
    if (bind(MySocket, (struct sockaddr*) &sad, sizeof(sad)) < 0) 
        ErrorHandler("bind() failed.\n");
        closesocket(MySocket);
        ClearWinSock();
        return 0;
    

    // SETTAGGIO DELLA SOCKET ALL'ASCOLTO
    if (listen(MySocket, QLEN) < 0) 
        ErrorHandler("listen() failed.\n");
        closesocket(MySocket);
        ClearWinSock();
        return 0;
    

    // ACCETTARE UNA NUOVA CONNESSIONE
    struct sockaddr_in cad; // structure for the client address
    int clientSocket; // socket descriptor for the client
    int clientLen; // the size of the client address

    printf("Waiting for a client to connect...");

    while (1) 
        clientLen = sizeof(cad); // set the size of the client address
        if ((clientSocket = accept(MySocket, (struct sockaddr *)&cad,
            &clientLen)) < 0) 
            ErrorHandler("accept() failed.\n");

            //RICEZIONE DATI TEST
            int bytesRcvd;
            int totalBytesRcvd = 0;
            int Csocket;
            Csocket = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);

            char buf[BUFFERSIZE]; // buffer for data from the server
            printf("Received: "); // Setup to print the echoed string


                if ((bytesRcvd = recv(Csocket, buf, BUFFERSIZE - 1, 0)) <= 0) 
                    ErrorHandler("recv() failed or connection closed prematurely");
                    closesocket(Csocket);
                    ClearWinSock();
                    return 0;
                                                            

                totalBytesRcvd += bytesRcvd; // Keep tally of total bytes
                buf[bytesRcvd] = '\0'; // Add \0 so printf knows where to stop
                printf("%s", buf); // Print the echo buffer


            // CHIUSURA DELLA CONNESSIONE
            closesocket(MySocket);
            ClearWinSock();
            return 0;
        
        printf("Handling client %s\n", inet_ntoa(cad.sin_addr));
    





和客户端:

#include "stdafx.h"
#include <winsock.h>
#include <stdio.h>
#include <stdlib.h>

#define BUFFERSIZE 512
#define PROTOPORT 5193

void ErrorHandler(char *errorMessage) 
    printf(errorMessage);


void ClearWinSock() 
    WSACleanup();



int main(void) 

    WSADATA wsaData;
    int iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);

    if (iResult != 0) 
        printf("error at WSASturtup\n");
        return 0;
                      

    // CREAZIONE DELLA SOCKET
    int Csocket;
    Csocket = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (Csocket < 0) 
        ErrorHandler("socket creation failed.\n");
        closesocket(Csocket);
        ClearWinSock();
        return 0;
                    

    // COSTRUZIONE DELL’INDIRIZZO DEL SERVER
    struct sockaddr_in sad;
    memset(&sad, 0, sizeof(sad));
    sad.sin_family = AF_INET;
    sad.sin_addr.s_addr = inet_addr("127.0.0.1"); // IP del server
    sad.sin_port = htons(5193); // Server port

    // CONNESSIONE AL SERVER
    if (connect(Csocket, (struct sockaddr *)&sad, sizeof(sad)) < 0)
    
        ErrorHandler("Failed to connect.\n");
        closesocket(Csocket);
        ClearWinSock();
        return 0;
    

    char* inputString = "prova"; // Stringa da inviare
    int stringLen = strlen(inputString); // Determina la lunghezza


    // INVIARE DATI AL SERVER
    if (send(Csocket, inputString, stringLen, 0) != stringLen) 
        ErrorHandler("send() sent a different number of bytes than expected");

        closesocket(Csocket);
        ClearWinSock();
        return 0;
    


    // RICEVERE DATI DAL SERVER
    int bytesRcvd;
    int totalBytesRcvd = 0;
    char buf[BUFFERSIZE]; // buffer for data from the server
    printf("Received: "); // Setup to print the echoed string

    while (totalBytesRcvd < stringLen) 
        if ((bytesRcvd = recv(Csocket, buf, BUFFERSIZE - 1, 0)) <= 0) 
            ErrorHandler("recv() failed or connection closed prematurely");
            closesocket(Csocket);
            ClearWinSock();
            return 0;
                                                                        
        totalBytesRcvd += bytesRcvd; // Keep tally of total bytes
        buf[bytesRcvd] = '\0'; // Add \0 so printf knows where to stop
        printf("%s", buf); // Print the echo buffer
                                        

    // CHIUSURA DELLA CONNESSIONE
    closesocket(Csocket);
    ClearWinSock();
    printf("\n"); // Print a final linefeed
    system("pause");
    return(0);

我在输出从客户端传递到服务器的字符串时遇到问题:“prova”。

谁能告诉我错误在哪里?该代码没有给我任何错误。

【问题讨论】:

C 和 C++ 是不同的语言。这看起来像 C,但是当您明确指出 C++ 时,您可能会编译为 C++。随意更改标签和文本 【参考方案1】:

您仅在accept 失败时接收数据:

if ((clientSocket = accept(MySocket, (struct sockaddr *)&cad,
        &clientLen)) < 0) 
        ErrorHandler("accept() failed.\n");

        int bytesRcvd;
        int totalBytesRcvd = 0;
        ...

您需要做的只是添加一个else 案例:

if ((clientSocket = accept(MySocket, (struct sockaddr *)&cad,
        &clientLen)) < 0) 
        ErrorHandler("accept() failed.\n");
 else 

        int bytesRcvd;
        int totalBytesRcvd = 0;
        ... // receive code here

        // clientSocket is the socket to communicate with client
        // call recv on it, not the other socket you created in the loop


【讨论】:

很好看。您可能会认为,当 OP 使用其调试器单步执行时,很容易发现这样的严重错误...... :( 我添加了一个 else,现在黑色控制台在 1 秒内打开和关闭,我不知道为什么 :( @MarinaBruno 你是否也删除了 Csocket 的创建,并在 clientSocket 上调用了 recv? 是的,我只是这样做,但是当我开始编译时,控制台会在几秒钟内打开和关闭...... @MarinaBruno 你能用新代码更新你的帖子吗?【参考方案2】:

accept() 调用返回“clientSocket”,您会立即忽略它并设想一些新的“Csocket”来接收。

不要那样做。

if ((bytesRcvd = recv(clientSocket, buf, BUFFERSIZE - 1, 0)) <= 0) 

【讨论】:

【参考方案3】:

这是新的服务器端:

#include "stdafx.h"
#include <winsock.h>
#include <stdio.h>
#include<stdlib.h>

#define PROTOPORT 5193
#define QLEN 6
#define BUFFERSIZE 512

void ErrorHandler(char *errorMessage)

    printf(errorMessage);



void ClearWinSock()

#if defined WIN32
    WSACleanup();
#endif



int main(int argc, char *argv[])

    int port;

    if (argc > 1)
        port = atoi(argv[1]);
    else
        port = PROTOPORT;

    if (port < 0) 
        printf("Bad port number %s \n", argv[1]);
        return 0;
    

#if defined WIN32
    WSADATA wsaData;
    int iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);

    if (iResult != 0) 
        ErrorHandler("Error at WSAStartup()\n");
        return 0;
    
#endif

    //creazione della socket
    int MySocket;
    MySocket = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (MySocket < 0) 
        ErrorHandler("socket creation failed.\n");
        ClearWinSock();
        return 0;
    

    //ASSEGNAZIONE DI UN INDIRIZZO ALLA SOCKET
    struct sockaddr_in sad;
    memset(&sad, 0, sizeof(sad)); // ensures that extra bytes contain 0
    sad.sin_family = AF_INET;
    sad.sin_addr.s_addr = inet_addr("127.0.0.1");
    sad.sin_port = htons(port); /* converts values between the host and
                                network byte order. Specifically, htons() converts 16-bit quantities
                                from host byte order to network byte order. */
    if (bind(MySocket, (struct sockaddr*) &sad, sizeof(sad)) < 0) 
        ErrorHandler("bind() failed.\n");
        closesocket(MySocket);
        ClearWinSock();
        return 0;
    

    // SETTAGGIO DELLA SOCKET ALL'ASCOLTO
    if (listen(MySocket, QLEN) < 0) 
        ErrorHandler("listen() failed.\n");
        closesocket(MySocket);
        ClearWinSock();
        return 0;
    

    // ACCETTARE UNA NUOVA CONNESSIONE
    struct sockaddr_in cad; // structure for the client address
    int clientSocket; // socket descriptor for the client
    int clientLen; // the size of the client address

    printf("Waiting for a client to connect...");

    while (1) 
        clientLen = sizeof(cad); // set the size of the client address
        if ((clientSocket = accept(MySocket, (struct sockaddr *)&cad,
            &clientLen)) < 0) 
            ErrorHandler("accept() failed.\n");
        else

            //RICEZIONE DATI TEST
            int bytesRcvd;
            int totalBytesRcvd = 0;

            char buf[BUFFERSIZE]; // buffer for data from the server
            printf("Received: "); // Setup to print the echoed string


                if ((bytesRcvd = recv(clientSocket, buf, BUFFERSIZE - 1, 0)) <= 0) 
                    ErrorHandler("recv() failed or connection closed prematurely");
                    closesocket(clientSocket);
                    ClearWinSock();
                    return 0;

                totalBytesRcvd += bytesRcvd; // Keep tally of total bytes
                buf[bytesRcvd] = '\0'; // Add \0 so printf knows where to stop
                printf("%s", buf); // Print the echo buffer
                 Sleep(10);


            // CHIUSURA DELLA CONNESSIONE
            closesocket(MySocket);
            ClearWinSock();
            return 0;
        
        printf("Handling client %s\n", inet_ntoa(cad.sin_addr));
        system("pause");
    


【讨论】:

你又完成了!仔细查看“if”语句的范围:( 修正你的缩进,这让所有人都感到困惑,包括你自己。 另外,如果您修复代码并提出新版本,请编辑问题并将新版本附加到旧版本下方。那个,或者发布一个全新的问题,也许引用旧的问题。 另外,sleep() 调用是不必要且令人困惑的。 另外,在调试器下运行代码。如果您在原始帖子之前这样做,您会发现这些控制流错误:(

以上是关于套接字编程c ++ windows,看不到从服务器接收到的消息[关闭]的主要内容,如果未能解决你的问题,请参考以下文章

C 中的 Windows 套接字编程

Windows 上的 C 中的套接字编程(服务器、使用 select() 和 fd_set 的多线程)

在 Windows 上进行 C 套接字编程时,我需要替换哪些等效的标头、函数和数据类型?

通过 C 中的套接字编程处理多个客户端

C# Windows 应用程序从流套接字读取数据不可理解

vs2008和socket编程