Understanding of UDP Socket buffer
The UDP socket sends and receives packets using sendto and recvfrom. It can be analogous to the TCP socket's connect and accept. The parameter identifies the Peer to be sent, or the IP address and port of the Peer to be received; the behavior of UDP socket connect only tells the kernel: "Let me filter, I only care about this peer packet." read, write, Recv, can be used on connected UDP sockets, send function. If it is determined that the object only communicates with one peer, connect is selected. More importantly, the buffer zone of UDP socket queues packets, A recvfrom call is used to extract a message, which is different from the TCP byte stream method. For this reason, we cannot first read certain application-layer headers in UPD, and then read the specific data elegantly Based on the length field in the header. This will cause errors and confusion; this is often done in TCP.
The following is an example. The client sends the content with a certain length, receives the content from the client, reads the first part, and then the specific data block. If UDP is used, an error occurs. You can use TCP. The Code is as follows (for the complete code, see file-transfer ):
typedef struct{unsigned char fp[20];int chunk_id;short flags;short chunk_len;char data[0];}TransferUnit; // some flags for this chunk transfered.enum{ UNIT_NEED_DEDU = 0x0001, // need deduplication UNIT_FILE_START = 0x0002, // first gram , file metadata UNIT_FILE_END = 0x0004, CHUNK_OTHER = 0x0008, // other for extension};void recvFile(char name[20],int sockfd){ int ret,fd;mode_t fdmode = (S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH); unsigned char mesg[MAX]; fd_set rdset; struct timeval tv; int rlen, wlen, chunklen; int i;TransferUnit *header = (TransferUnit *)malloc(sizeof(TransferUnit)); fd = open(name,O_RDWR|O_CREAT|O_APPEND,fdmode); if(fd == -1) { printf("open file %s error:%s \n",name,strerror(errno)); exit(-1); }while(1){ memset(mesg, 0, sizeof(mesg));// read the gram header first rlen = read(sockfd, header, sizeof(TransferUnit));//printf("%d\n", rlen); if(rlen != sizeof(TransferUnit) ){ printf("read sockfd error %s\n",strerror(errno)); exit(-1); }// recv file end if((header->flags ^ UNIT_FILE_END) == 0){ printf("recv end.\n"); break; }// recv file metadata if((header->flags ^ UNIT_FILE_START) == 0){ int len = header->chunk_len; // metadata length...char metadata[100] = {0};printf("==== begin file recv ====,metadata len = %d\n", len);if((rlen = read(sockfd, mesg, len)) == len){mesg[len] = '\0';printf("File name : %s\n", mesg);} continue; }chunklen = header->chunk_len;// read the actual chunk data rlen = read(sockfd, mesg, chunklen);//printf("chunk_id:%d,chunk_len:%d \n", header->chunk_id, header->chunk_len); if(rlen != chunklen ){ printf("read chunk data error %s\n",strerror(errno)); exit(-1); }// write the chunk data to this file wlen = write(fd,mesg,rlen); if(wlen != rlen ){ printf("write error %s\n",strerror(errno)); exit(-1); } printf("The %d times write\n",i);} close(fd);}
Understanding of UDP Socket buffer