服务器接收客户端发送过来的数据流,且以结构体解析案例
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#define INVALID_SOCKET -1
#define SOCKET_ERROR -1
struct Header
{
unsigned int Makelength;
unsigned int Modellength;
};
struct CarData {
int Vin; //Unique Vehicle ID
char* Make; //A string containing the make of the car
char* Model; //A string containing the model of the car
float MSRP; //Suggest Manufacturers Retail Price in $
};
struct packet {
struct CarData car;
struct Header Head;
};
void DeserializeCarData(char* RxBuffer, struct packet* pkt) {
memcpy(&pkt->Head, RxBuffer, sizeof(pkt->Head));
pkt->car.Make = (char*)malloc(pkt->Head.Makelength);
pkt->car.Model = (char*)malloc(pkt->Head.Modellength);
if (pkt->car.Make == NULL || pkt->car.Model == NULL)
{
exit(EXIT_FAILURE);
}
memcpy(&pkt->car.Vin, RxBuffer + sizeof(pkt->Head), sizeof(pkt->car.Vin));
memcpy(pkt->car.Make, RxBuffer + sizeof(pkt->Head) + sizeof(pkt->car.Vin), pkt->Head.Makelength - 1);
pkt->car.Make[pkt->Head.Makelength - 1] = '\0';
memcpy(pkt->car.Model, RxBuffer + sizeof(pkt->Head) + sizeof(pkt->car.Vin) + pkt->Head.Makelength, pkt->Head.Modellength - 1);
pkt->car.Model[pkt->Head.Modellength - 1] = '\0';
memcpy(&pkt->car.MSRP, RxBuffer + sizeof(pkt->Head) + sizeof(pkt->car.Vin) + pkt->Head.Makelength + pkt->Head.Modellength, sizeof(pkt->car.MSRP));
}
int main()
{
struct sockaddr_in SvrAddr;
int WelcomeSocket, ConnectionSocket;
//Data buffers
char RxBuffer[128] = {};
//create welcoming socket at port and bind local address
if ((WelcomeSocket = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET)
{
printf("ERROR: Failed to create WelcomeSocket\n");
return 0;
}
SvrAddr.sin_family = AF_INET;
SvrAddr.sin_addr.s_addr = INADDR_ANY;
SvrAddr.sin_port = htons(27000);
if ((bind(WelcomeSocket, (struct sockaddr*)&SvrAddr, sizeof(SvrAddr))) == SOCKET_ERROR)
{
printf("ERROR: Failed to bind WelcomeSocket\n");
close(WelcomeSocket);
return 0;
}
//Specify the maximum number of clients that can be queued
if (listen(WelcomeSocket, 1) == SOCKET_ERROR)
{
printf("ERROR: Failed to start Listening Port\n");
close(WelcomeSocket);
return 0;
}
printf("Waiting for client connection\n");
ConnectionSocket = SOCKET_ERROR;
while (1)
{
//wait for an incoming connection from a client
if ((ConnectionSocket = accept(WelcomeSocket, NULL, NULL)) == SOCKET_ERROR)
{
printf("oops! Something went wrong\n");
return 0;
}
else
{
printf("Connection Established\n");
/***********************************
* TBD - Insert your Lab 6 code here*
************************************/
while (1) {
// 1. empty RxBuffer
memset(RxBuffer, 0, sizeof(RxBuffer));
// 2. receive RxBuffer
int numBytesRecv = recv(ConnectionSocket, RxBuffer, sizeof(RxBuffer), 0);
if (numBytesRecv == SOCKET_ERROR || numBytesRecv == 0) {
break; // Connection closed or error
}
struct packet pkt;
DeserializeCarData(RxBuffer, &pkt);
// Check if Vin is 0, if so, break the loop
if (pkt.car.Vin == 0) {
break;
}
printf("VIN: %d\n", pkt.car.Vin);
printf("make of the car: %s\n", pkt.car.Make);
printf("model of the car: %s\n", pkt.car.Model);
printf("Retail Price: %.2f\n", pkt.car.MSRP);
free(pkt.car.Make);
free(pkt.car.Model);
}
close(ConnectionSocket);
}
}
close(ConnectionSocket);
return 1;
}