在套接字上发送结构

时间:2015-02-27 04:46:53

标签: c sockets struct

我对使用套接字很新,到目前为止只能通过套接字发送char []

现在,我正在尝试在套接字上发送struct,并且不确定如何执行此操作。我有以下struct

struct student_rec {
    char name[25];
    float gpa;
    int pid;
};

我用以下

初始化了
struct student_rec stu

strcpy(stu.name, "Mike McDonald");
stu.gpa = 2.5;
stu.pid = 0x12345678;

我可以毫无问题地发送stu.name,但不确定在发送sendto()时方法struct使用哪些参数。

客户端

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdio.h>
#include <string.h>

/* This program sends a message in datagram to the receiver and waits
   for reply. */

#define MSG "CIS 454/554 is a great course!!!"

#define BUFMAX 2048

struct student_rec {
    char name[25];
    float gpa;
    int pid;
};

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

  int sk;
  char buf[BUFMAX];

  struct student_rec stu;
  struct sockaddr_in remote;
  struct hostent *hp;

  strcpy(stu.name, "Mike McDonald");
  stu.gpa = 2.5;
  stu.pid = 0x12345678;

  /* Create an Internet domain datagram socket */
  sk = socket(AF_INET,SOCK_DGRAM,0);

  remote.sin_family = AF_INET;

  /* Get the remote machine address from its symbolic name 
     given in the command line argument */

  hp = gethostbyname(argv[1]);
  if (hp == NULL) {
      printf("Can't find host name. %s\n", argv[1]);
      exit (1);
  }

  bcopy(hp->h_addr,&remote.sin_addr.s_addr,hp->h_length);
  /* get the remote port number from the command line */
  remote.sin_port = ntohs(atoi(argv[2]));

  sendto(sk,stu.name,strlen(stu.name)+1,0,&remote,sizeof(remote));/* Send the message */
  read(sk,buf,BUFMAX); /* Get the reply */
  printf("%s\n",buf); 

  close(sk);
}

服务器

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <fcntl.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>

/* This program creates an Internet domain datagram socket, binds a
   name to it, reads from it, and then replies to the sender. */

#define MSG "Are you sure ? I doubt!!!"

#define BUFMAX 2048

struct student_rec {
    char name[25];
    float gpa;
    int pid;
};

main()
{
  struct sockaddr_in local, remote;
  int sk,rlen=sizeof(remote),len=sizeof(local);
  char buf[BUFMAX];

  /* Create an Internet domain datagram socket from which to read */
  sk = socket(AF_INET,SOCK_DGRAM,0);

  struct student_rec stu;

  strcpy(stu.name, "Mike McDonald");
  stu.gpa = 2.5;
  stu.pid = 0x12345678;

  local.sin_family = AF_INET; /* Define the socket domain */
  local.sin_addr.s_addr = INADDR_ANY; /* Wildcard mach. addr */
  local.sin_port = 0; /* Let the system assign a port */
  bind(sk,&local,sizeof(local)); 

  getsockname(sk,&local,&len); /* Get the port number assigned */
  printf("socket has port %d\n",htons(local.sin_port)); /* Publish the number */


  /* Read from the socket */
  recvfrom(sk,buf,BUFMAX,0,&remote,&rlen);
  printf("%s\n",buf);
  sendto(sk,stu.name,strlen(stu.name)+1,0,&remote,sizeof(remote)); 

  close(sk);
}

我认为我对要替换strlen(stu.name)的内容感到困惑,因为我现在正在发送整个struct

我可以使用for循环来阅读struct的每个元素,还是有一些参数可以传递给sendto()来执行此操作?

1 个答案:

答案 0 :(得分:5)

您应该将struct序列化为xml,json,text或类似格式,并在另一端将其读回:

/* Tx */
struct student_rec s = {...};
char txt[100];
const int len = sprintf(txt, "%d,%f,%s", s.pid, s.gpa, s.name);
send_txt(txt);
/* Rx */
char txt[100];
recv_txt(txt);
struct student_rec s
sscanf(txt, "%d,%f,%s", &s.pid, &s.gpa, s.name);