在TCP / IP套接字中从客户端向服务器发送结构

时间:2013-12-16 10:57:34

标签: c sockets tcp

我的头文件structure.h中有以下结构。现在我需要在main.c文件中使用此结构。

我需要用一些值填充这个结构,我需要将它从TCP / IP客户端发送到同一系统上的TCP / IP服务器。

#ifndef STRUCTURE_H
#define STRUCTURE_H

typedef struct
{
    unsigned int variable3;
    char variable4[8];
}NUMBER_ONE,*PNUMBER_ONE;


typedef struct
{
    unsigned int variable5;
    char variable6[8];
}NUMBER_TWO,*PNUMBER_TWO;

typedef struct
{
    char name[32];
    unsigned int a;
    unsigned int b;
    NUMBER_ONE variable1;
    NUMBER_TWO variable2;
}NUMBER_THREE,*PNUMBER_THREE;

#endif

我试过这个但是,我不擅长C,所以请以上述结构为例,请有人告诉我怎么做吗?直到套接字连接建立对我来说没问题, 但在建立连接后,如何将此结构从客户端发送到服务器?

我在Linux Ubuntu 12.04系统中这样做。

2 个答案:

答案 0 :(得分:2)

使用套接字发送信息时使用三种方式:

1)固定大小的消息(我们将使用它,加上假设我们在相同的机器上进行字节顺序匹配)。简单地说,就像我们将发送100个字节并在接收时我们将读取100bytes

2)message.len + message。(首先我们发送消息len然后发送消息本身。主要用于二进制发送接收)

3)标记方法(主要用于发送短信或命令。用\ n换行来标记标记)

接下来代表我们的数据(序列化)。我们可以直接编写我们的对象并在不需要额外努力的情况下检索它。对象将与内存中的对象相同。

// PNUMBER_THREE structAddr;
    send(socket_id, structAddr, sizeof(NUMBER_THREE), 0);

 write(socket_id, structAddr, sizeof(NUMBER_THREE));

或更安全

write_socket(socket_id, structAddr, sizeof(NUMBER_THREE));
//It is safer to do so though we are using blocking mode
int write_socket(int fd,const char *buf,int len){
    int currentsize=0;
    while(currentsize<len){
        int count=write(fd,buf+currentsize,len-currentsize);
        if(count<0) return -1;
        currentsize+=count;
    }
    return currentsize;
}

阅读时我们将使用相同结构加上它必须符合条件sizeof(NUMBER_THREE)==SizeInsideClient //SizeInsideClient is sizeof on client SizeInsideClient=sizeof(NUMBER_THREE)

   //SizeInsideClient structure size on client program
    assert(sizeof(NUMBER_THREE)==SizeInsideClient);
    readblock(socket_id,structAddr,sizeof(NUMBER_THREE));

    int readblock(int fd, char* buffer, int len) {
        int ret  = 0;
        int count = 0;
        while (count < len) { 
            ret = read(fd, buffer + count, len - count);
            if (ret <= 0) { 
                return (-1);
            }
            count += ret;
        }
        return count;

    }

答案 1 :(得分:0)

没有错误检查的简短示例:

服务器

struct sockaddr_in serv_addr; 

listenfd = socket(AF_INET, SOCK_STREAM, 0);

serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
serv_addr.sin_port = htons(5000); 
bind(listenfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr)); 

listen(listenfd, 10);

while(1)
{
    connfd = accept(listenfd, (struct sockaddr*)NULL, NULL); 
    snprintf(sendBuff, sizeof(sendBuff), "%.24s\r\n", ctime(&ticks));
    write(connfd, sendBuff, strlen(sendBuff)); 
    close(connfd);
    sleep(1);
 }

<强>客户端

 struct sockaddr_in serv_addr; 

 sockfd = socket(AF_INET, SOCK_STREAM, 0);

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

 inet_pton(AF_INET, argv[1], &serv_addr.sin_addr); 
 connect(sockfd,
 (struct sockaddr *)&serv_addr, sizeof(serv_addr))

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

<强>陷阱

不是“安全”所以发送普通结构。迟早你会处理字节顺序(字节顺序),打包(即使使用#pragma pack仍然会出现问题)和类型的大小如'int'可能会因平台而异