⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ms_udp.c

📁 1. 8623L平台
💻 C
字号:
/* * * Copyright (c) Sigma Designs, Inc. 2005. All rights reserved. * */#define ALLOW_OS_CODE 1#include "rmdef/rmdef.h"#include "rmcore/include/rmascii.h"#include <stdio.h>#include "ms_udp.h"#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <string.h>#include <errno.h>#include <netdb.h>#include <time.h>#include <sys/poll.h>#define MAX_BUFFER_SIZE 1024static RMuint8 udp_buffer[MAX_BUFFER_SIZE];struct ms_udp_socket_s {	int sockfd;	struct sockaddr_in name;};/** * Create a new UDP socket, connected to address *address by default * * @param address - IP address of the MS server * @return a valid ms_udp_socket_t, or NULL on error */ms_udp_socket_t * open_ms_udp_socket(RMascii *address){	ms_udp_socket_t *ms_socket = NULL;	RMascii *paddress = NULL;	RMuint16 port;	RMascii *host;	RMascii *port_string;	struct hostent *hostinfo;	int status;	ms_socket = (ms_udp_socket_t *)RMMalloc(sizeof(ms_udp_socket_t));	if (ms_socket == NULL)		return NULL;	ms_socket->sockfd = socket(PF_INET, SOCK_DGRAM, 0);	if (ms_socket->sockfd < 0){		RMDBGLOG((ENABLE,"Error creating socket : %s\n", strerror(errno)));		goto error;	}	paddress = RMMallocAndDuplicateAscii(address);	if (paddress == NULL)		goto error;	if (RMFindAsciiCharacter(paddress, ':', &host))		host++;	else		goto error;	if (RMFindAsciiCharacter(host, ':', &port_string)){		port_string[0] = 0;		port_string++;		RMasciiToUInt16(port_string, &port);		port = htons(port);	} else		goto error;	ms_socket->name.sin_family = AF_INET;	ms_socket->name.sin_port = port;	hostinfo = gethostbyname (host);	if (hostinfo == NULL)	{		RMDBGLOG((ENABLE, "Error getting host address for %s : %s\n", host, strerror(errno)));		goto error;	}	ms_socket->name.sin_addr = *(struct in_addr *) hostinfo->h_addr;	status = connect(ms_socket->sockfd, (struct sockaddr *)&(ms_socket->name), sizeof(ms_socket->name));	if (status < 0){		RMDBGLOG((ENABLE, "Error connecting the socket : %s\n", strerror(errno)));		goto error;	}	RMFree(paddress);	return ms_socket;error :	if (ms_socket)		RMFree(ms_socket);	if (paddress)		RMFree(paddress);	return NULL;}		/** * Close a UDP connection, and free associated resources *  * @param ms_socket - the socket to close */void close_ms_udp_socket(ms_udp_socket_t *ms_socket){	int status;		if (ms_socket == NULL)		return;	status = shutdown(ms_socket->sockfd, SHUT_RDWR);	if (status < 0)		RMDBGLOG((ENABLE,"Error closing MS socket : %s\n", strerror(errno)));	RMFree(ms_socket);}				/** * Send a UDP packet and wait for the anser for a given time. This function is * not reentrant, the answer should not be freed and a subsequent call to * ms_udp_send_receive will modify it. * * @param ms_socket - ms_socket to use * @param message * @param message_size  * @param answer - answer received * @param answer_size - size of the answer * @param small_dealy_ms - delay between attempts (ms) * @param big_delay_s - global delay (s) * @return RM_OK on success, RM_ERROR if no message received in the given delay */RMstatus ms_udp_send_receive(ms_udp_socket_t *ms_socket, 		             RMuint8 *message, RMuint32 message_size,                             RMuint8 **answer, RMuint32 *answer_size, 			     RMuint32 small_dealy_ms,			     RMuint32 big_delay_s){	ssize_t sent_bytes;	time_t end_time;	RMuint32 attempt = 0;	struct pollfd mpoll;	int status;	if (ms_socket == NULL ||	    message == NULL ||	    message_size == 0)		return RM_ERROR;	end_time = time(NULL) + (time_t) big_delay_s;	while (end_time > time(NULL)){		/* Try sending the message again */		RMDBGLOG((ENABLE,"Send %ld bytes message, attempt %ld\n", message_size, attempt));		sent_bytes = send(ms_socket->sockfd, (void *)message, (size_t)message_size, 0);		if (sent_bytes < 0 ){			RMDBGLOG((ENABLE,"Error sending UDP message : %s\n", strerror(errno)));			goto error;		} else if ((unsigned) sent_bytes != message_size) {			RMDBGLOG((ENABLE,"Error, only %ld/%ld bytes sent\n", sent_bytes, message_size));			goto error;		}		/* Wait for answer */		mpoll.fd = ms_socket->sockfd;		mpoll.events = POLLIN | POLLPRI;		status = poll(&mpoll, 1, (int) small_dealy_ms);		if (status < 0 ){			RMDBGLOG((ENABLE,"Error polling socket : %s\n", strerror(errno)));			goto error;		} else if ( status == 0 ) {			RMDBGLOG((ENABLE,"Poll timed out ...\n"));			attempt++;			continue;		}		/* Something happened in time */		if (mpoll.revents & (POLLIN|POLLPRI)){			int nread;						nread = recv(ms_socket->sockfd, udp_buffer, MAX_BUFFER_SIZE, MSG_DONTWAIT);			if (nread < 0){				RMDBGLOG((ENABLE,"Error reading MS socket : %s\n", strerror(errno)));				goto error;			} else if (nread == MAX_BUFFER_SIZE) {				RMDBGLOG((ENABLE, "Error, too many data received\n"));				goto error;			}			RMDBGLOG((ENABLE,"Received %ld bytes from MS server\n", nread));			*answer = udp_buffer;			*answer_size = nread;			return RM_OK;		} else {			RMDBGLOG((ENABLE,"Errorm, unexpected event happened\n"));			goto error;		}	}	RMDBGLOG((ENABLE,"Global timeout of %ld seconds reached, abort\n", big_delay_s));error:	return RM_ERROR;}					

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -