[英]Need to print char* data of a structure in server.c program coming from client.c through UDP socket program C
我正在做我的學校作業,這要求我將一個包含字符指針的結構從客戶端程序傳遞到服務器,並在 Server.c 程序中打印結構數據。 I am being able to pass the structure properly and being able to retrieve the integer data from the structure in server.c, but I am getting an error "Segmentation fault" when I try to print the char* data in the server.c program來自 Client.c 程序。 我如何解決它?
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<sys/types.h>
#include<sys/socket.h>
#define PORT 8080
struct StudentInfo
{
char* name;
int roll;
}student;
int main()
{
student.name=(char*)malloc( 50 * sizeof(char));
student.name="Sara You";
student.roll=124;
int network_socket=socket(AF_INET, SOCK_DGRAM, 0);
struct sockaddr_in serveraddr;
memset(&serveraddr, 0, sizeof(serveraddr));
serveraddr.sin_family=AF_INET;
serveraddr.sin_port=htons(PORT);
serveraddr.sin_addr.s_addr=INADDR_ANY;
sendto(network_socket, &student, sizeof(student),0, (struct sockaddr*) &serveraddr, sizeof(serveraddr));
close(network_socket);
}
服務器.c
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<sys/types.h>
#include<arpa/inet.h>
#include<netinet/in.h>
#include<sys/socket.h>
#include<string.h>
#define PORT 8080
struct StudentInfo
{
char* name;
int roll;
} student1;
int main()
{
student1.name=(char*)malloc( 50 * sizeof(char));
struct sockaddr_in serveraddr, cliaddr;
int network_socket=socket(AF_INET, SOCK_DGRAM, 0);
memset(&serveraddr,0,sizeof(serveraddr));
memset(&cliaddr,0,sizeof(cliaddr));
serveraddr.sin_family=AF_INET;
serveraddr.sin_port=htons(PORT);
serveraddr.sin_addr.s_addr=INADDR_ANY;
bind(network_socket, (struct sockaddr*) &serveraddr, sizeof(serveraddr));
int len=sizeof(cliaddr);
recvfrom(network_socket, &student1, sizeof(student1), 0, (struct sockaddr*) &cliaddr, &len);
printf("Name %s: ", student1.name); //Segmentation fault
printf("Name %d: ", student1.roll);
}
如果您不介意將學生姓名限制為小於 100 個字節,則可以輕松解決此問題。 看起來您正在發送整個結構而沒有考慮字節順序。 因此,如果客戶端和服務器上的字節順序匹配,那么只需更改結構定義即可解決問題。 當然,通過將 memory 作為結構的名稱部分,您不必分配 memory 並且您必須使用strcpy
而不是分配指針。 像這樣:
struct StudentInfo {
char name[100];
int roll;
} student;
int main (int argc, char *argv[]) {
//student.name=(char*)malloc( 50 * sizeof(char));
//student.name="Sara You";
strcpy(student.name, "Sara You"); // check length, truncate, or send multiple messages
更新 1
如果您必須序列化您發送的內容並反序列化您收到的內容,那么您可以使用這兩個函數返回可以free
的內容:
char * serializeStudent (struct StudentInfo *stu) {
char *rval;
if (!stu || !stu->name) {
// errno = EINVAL;
return 0;
}
rval = malloc(strlen(stu->name) + 21); // never cast malloc
if (!rval) {
return 0; // errno will be set by malloc
}
sprintf(rval, "%10d%10d%s", stu->roll, strlen(stu->name), stu->name);
return rval;
}
發送前調用serializeStudent
,發送它返回的字符串(如果不為null),發送成功后free
該字符串。
struct StudentInfo * deserializeSerializedStudent (char *ser) {
struct StudentInfo *rval;
if (!ser) {
// errno = EINVAL;
return 0;
}
rval = malloc(sizeof(*rval));
if (!rval) {
return 0; // errno will be set by malloc
}
int len;
int n = sscanf(ser, "%10d%10d", rval->roll, &len);
if (n != 2) {
// errno = EINVAL;
free(rval);
return 0;
}
rval->name = malloc(len+1);
if (!rval->name) {
free(rval);
return 0; // errno will be set by malloc
}
n = sscanf(ser+20, "%*s", len, rval->name);
if (n != 1) {
// errno = EINVAL;
free(rval);
return 0;
}
return rval;
}
在收到您知道的完整字符串后調用deserializeSerializedStudent
。 然后對結構做你需要的事情,然后在釋放它包含的字符串后釋放它。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.