1

char 配列を使用してソケット経由でデータを送受信できますが、構造体を送信する方法がわかりません。多くの記事を見つけましたが、それらは理解しにくいものです.. 私が知る限り、snprintf と呼ばれる関数を使用してデータのパケットを作成し、それを復活させるために他の関数を使用する必要があります。非常に信頼性が高く、簡単なデータ転送方法を探しています..これは、char配列を介して送信するために作成したコードです

int main()
{
    int listenfd = 0, connfd = 0;
    struct sockaddr_in serv_addr; 

    char sendBuff[1025];
    time_t ticks;
    printf("\n\n...Server is starting up...\n\n");
    listenfd = socket(AF_INET, SOCK_STREAM, 0);

    memset(&serv_addr, '0', sizeof(serv_addr));
    memset(sendBuff, '0', sizeof(sendBuff)); 

    serv_addr.sin_family = AF_INET;
    serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    serv_addr.sin_port = htons(4567);

    bind(listenfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr));
    printf("Bind successful\n");
    listen(listenfd, 10);
    printf("Ready: Waiting for clients\n");
    while(1)
    {
        connfd = accept(listenfd, (struct sockaddr*)NULL, NULL); 
        ticks = time(NULL);
        snprintf(sendBuff, sizeof(sendBuff), "%.24s\r\n", ctime(&ticks));
        write(connfd, sendBuff, strlen(sendBuff));
        close(connfd);
        sleep(1);
    }

クライアント

int main(int argc, char *argv[])
{
    int sockfd = 0 /*Socket Descriptor*/, n = 0;
    char recvBuff[1024];
    struct sockaddr_in serv_addr; 

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

    memset(recvBuff, '0',sizeof(recvBuff));
    if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
        printf("\n Error : Could not create socket \n");
        return 1;
    } 

    memset(&serv_addr, '0', sizeof(serv_addr)); 
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_port = htons(4567); 
    if(inet_pton(AF_INET, argv[1], &serv_addr.sin_addr)<=0) {
        printf("\n inet_pton error occured\n");
        return 1;
    } 

    if( connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) {
       printf("\n Error : Connect Failed \n");
       return 1;
    } 

    while ( (n = read(sockfd, recvBuff, sizeof(recvBuff)-1)) > 0) {
        recvBuff[n] = 0;
        if(fputs(recvBuff, stdout) == EOF) {
            printf("\n Error : Fputs error\n");
        }
    } 

    if(n < 0) {
        printf("\n Read error \n");
    } 

    return 0;
}
4

3 に答える 3

6

構造を送信する場合、要約すると、しないでください。同様に、構造体ポインター、sizeof 演算子、およびソケット send() を使用しようとしないでください。すべてうまくいくと期待してはいけません。

むしろ、構造体のメンバーは、移植可能な共通コードによってソケット接続の両端で理解および管理される、明確に定義されたバイト形式で配置する必要があります。この形式 (プロトコルなど) には、構造体をバイト配列にアセンブルしたり、バイト配列から逆アセンブルしたりするための移植可能なルーチンが必要です。これらのルーチンをクライアント側とサーバー側の両方で使用し、サイズ、数値のエンディアンなどを考慮することが、(a) 正しく、(b) 移植性の両方を実現する唯一の方法です。

利用可能な一般的なソリューション (boost::serialization など) はありますが、最終的に特効薬はありません。したがって、すべてのオプションを検討し、可能な限り最も移植性が高く、最も単純なアプローチを採用してください。

于 2012-10-27T16:54:00.023 に答える
1

もう 1 つのオプションは、インターフェイス記述言語 (IDL) に基づいてコードを生成するアプリケーションを使用することです。2 つの優れたオプションは、Apache ThriftGoogle プロトコル バッファです。

于 2012-10-27T17:13:42.253 に答える