0

こんにちは、私はこのようにそれを渡そうとしています

typedef struct t_timeSliceRequest{
unsigned int processId;
unsigned int timeRequired;
int priority;
}timeSliceRequest;

struct t_timeSliceRequest request = { 1,2,1 };
sendFlag = send(socketID,(timeSliceRequest *) &request, sin_size ,0);

そしてサーバー側で

recvFlag = recv(socketID,(timeSliceRequest *) &request,sin_size,0);

しかし、ガベージを受け取り、recvが-1を返しても、助けてください

これは私の完全なコンデです

#include<sys/socket.h>
#include<sys/types.h>
#include<string.h>
#include<stdio.h>
#include<arpa/inet.h>
#include<time.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <netinet/in.h>

enum priority_e{ high, normal, low };

typedef struct t_timeSliceRequest{
    unsigned int processId;
    unsigned int timeRequired;
    int priority;
}timeSliceRequest;

typedef struct t_TimeSliceResponse {
    timeSliceRequest original_req;

    // Unix time stamp of when process was started on server
    unsigned int time_started;

    // Waiting and running time till end of CPU bust
    unsigned int ttl;

} TimeSliceResponse;


int main(int argc, char ** argv){
    int socketID = 0, clientID = 0;
    char sendBuffer[1024], recvBuffer[1024];
    time_t time;
    struct sockaddr_in servAddr, clientAddr;
    struct t_timeSliceRequest request = {1,1,0};

memset(sendBuffer, '0', sizeof(sendBuffer));
memset(recvBuffer, '0', sizeof(recvBuffer));

fprintf(stdout,"\n\n --- Server starting up --- \n\n");
fflush(stdout);

socketID = socket(AF_INET, SOCK_STREAM, 0);
if(socketID == -1){
    fprintf(stderr, " Can't create Socket");
    fflush(stdout);
}

servAddr.sin_family = AF_INET;
servAddr.sin_port = htons(5000);
servAddr.sin_addr.s_addr = htonl(INADDR_ANY);

int bindID, sin_size, recvFlag;
bindID = bind(socketID, (struct sockaddr *)&servAddr, sizeof(servAddr)); // Casting sockaddr_in on sockaddr and binding it with socket id
if(bindID!=-1){
    fprintf(stdout," Bind SucessFull");
    fflush(stdout);
    listen(socketID,5);
    fprintf(stdout, " Server Waiting for connections\n");
    fflush(stdout);
    while(1){
        sin_size = sizeof(struct sockaddr_in);
        clientID = accept(socketID, (struct sockaddr *) &clientAddr, &sin_size);
        fprintf(stdout,"\n I got a connection from (%s , %d)", inet_ntoa(clientAddr.sin_addr), ntohs(clientAddr.sin_port));
        fflush(stdout);
        sin_size = sizeof(request);
        recvFlag = recv(socketID, &request,sin_size,0);
        perror("\n Err: ");
        fprintf(stdout, "\n recvFlag: %d", recvFlag);
        fprintf(stdout, "\n Time Slice request received:\n\tPid: %d \n\tTime Required: %d ", ntohs(request.processId), ntohs(request.timeRequired));
        fflush(stdout);
        snprintf(sendBuffer, sizeof(sendBuffer), "%.24s\n", ctime(&time));
        write(clientID, sendBuffer, strlen(sendBuffer));
        close(clientID);
        sleep(1);
    }
}else{
    fprintf(stdout, " Unable to Bind");
}
close(socketID);
return 0;
}

クライアントコードは次のとおりです。

#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <arpa/inet.h>

enum priority_e{ high = +1, normal = 0, low = -1};

typedef struct t_timeSliceRequest{
    unsigned int processId;
    unsigned int timeRequired;
    int priority;
}timeSliceRequest;

int main(int argc, char *argv[])
{
    int socketID = 0 /*Socket Descriptor*/, n = 0;
    char recvBuffer[1024];
    memset(recvBuffer, '0',sizeof(recvBuffer));
    struct sockaddr_in servAddr;

    struct t_timeSliceRequest request = { 1,2,high };

    if(argc!=2){
        fprintf(stderr,"\n Usage: %s <ip of server> \n",argv[0]);
        return 1;
    }

    socketID = socket(AF_INET, SOCK_STREAM, 0);
    if(socketID == -1){
        fprintf(stderr, "\n Can't create socket \n");
        return 1;
    }

    servAddr.sin_family = AF_INET;
    servAddr.sin_port = htons(5000);

    if(inet_pton(AF_INET, argv[1], &servAddr.sin_addr)==-1){
        fprintf(stderr, "\n Unable to convert given IP to Network Form \n inet_pton Error");
        return 1;
    }

    int connectFlag, sendFlag = 0;
    connectFlag = connect(socketID, (struct sockaddr *)&servAddr, sizeof(servAddr));
    if(connectFlag == -1){
       fprintf(stderr, " Connection Failed\n");
       return 1;
    }

    int sin_size = sizeof(struct t_timeSliceRequest);
    fprintf(stdout, " \n %d \n %d \n %d", request.processId, request.timeRequired, request.priority);
    sendFlag = send(socketID, &request, sin_size ,0);
    fprintf(stdout, "\nSend Flag: %d\n", sendFlag);

    n = read(socketID, recvBuffer, sizeof(recvBuffer)-1);
    recvBuffer[n] = 0;
    fprintf(stdout, "%s",recvBuffer);
    if(n < 0){
        fprintf(stderr, " Read error\n");
    }
    return 0;
}

これは完全なコードで、「トランスポート エンドポイントが接続されていません」と表示されます

4

2 に答える 2

3

このような構造体をネットワーク経由で送信すると、相互運用性の問題が発生する可能性があることに注意してください。

  1. ソースと宛先のエンディアンが異なる場合、間違ったデータを受け取ることになります (htonlデータをネットワーク エンディアンに変換するような関数を使用することを検討してください) 。
  2. 構造体をパックする必要があります。そうしないと、異なるコンパイラが構造体の変数を異なる方法で整列させることができます (変数の整列についてのアイデアを得るには、これを参照してください)。

いずれにせよ、ENOTCONN2 つのホスト間の接続を確立する際にエラーが発生したことを示唆しています。

于 2012-10-29T09:55:38.373 に答える
0

ソケットが(ポート、アドレス)ペアにバインドされていない場合、トランスポートエンドポイントが接続されていませんというエラーが返されます。

サーバー側の場合は、accept呼び出しによって返されるソケット記述子を使用する必要があります。クライアントの場合-への呼び出しが成功すると返されるソケットを使用する必要がありますconnect

ところで、あなたのように構造を送ることは非常に危険です。コンパイラーは、ターゲットプラットフォームのいくつかのアライメント規則に準拠するために、構造体メンバーの間にパディングバイトを挿入する場合があります(プログラムには表示されませんが、構造体にスペースが必要です)。さらに、プラットフォームが異なればエンディアンも異なり、構造が完全に台無しになる可能性があります。クライアントとサーバーが異なるマシン用にコンパイルされている場合、構造のレイアウトとエンディアンは互換性がない可能性があります。この問題を解決するには、パック構造を使用できます。構造体をパックされたものとして宣言する方法は、コンパイラーによって異なります。GCCの場合、これは構造に特別な属性を追加することで実行できます。

この問題を解決する別の方法は、構造体の個々のフィールドを手動で生のバイトバッファに配置することです。受信側は、データが最初にそのバッファに入れられたのとまったく同じ方法で、このすべてのデータを取り出す必要があります。マルチバイト値(int、longなど)を保存するときにネットワークのバイト順序を考慮する必要があるため、このアプローチには注意が必要です。htonlそのためのhtons、、などの特別な関数のセットがありますntohs

更新しました

サーバー内:

recvFlag = recv(socketID, &request,sin_size,0);

ここにあるはずです

recvFlag = recv(clientID, &request,sin_size,0);

socketIDはパッシブソケットであり、接続のみを受け入れることができます(データを送信することはできません)。

さらに、の結果はaccept-1についてチェックされません。

于 2012-10-29T09:47:47.953 に答える