void rtsp_tcp_read_cb(struct ev_loop *loop, ev_io *w,
                      ATTR_UNUSED int revents)
{
    guint8 buffer[RTSP_BUFFERSIZE + 1] = { 0, };    /* +1 to control the final '\0' */
    int read_size;
    RTSP_Client *rtsp = w->data;
    int sd = rtsp->sd;

    /* if we're receiving data for an HTTP tunnel, we have to run it
       through the HTTP client's buffer. */
    if ( rtsp->pair != NULL )
        rtsp = rtsp->pair->http_client;

    if ( (read_size = recv(sd,
                           buffer,
                           sizeof(buffer),
                           0) ) <= 0 )
        goto client_close;

    stats_account_read(rtsp, read_size);

    if (rtsp->input->len + read_size > RTSP_BUFFERSIZE) {
        xlog(LOG_DBG,
                "RTSP buffer overflow (input RTSP message is most likely invalid).\n");
        goto server_close;
    }

    g_byte_array_append(rtsp->input, (guint8*)buffer, read_size);

    xlog(LOG_DBG, "rtsp request probe is %d. localhost:%s remote:%s", rtsp->pending_request, rtsp->local_host, rtsp->remote_host);
    RTSP_handler(rtsp);

    return;

 client_close:
    xlog(LOG_INF, "RTSP connection closed by client.");
    goto disconnect;

 server_close:
    xlog(LOG_INF, "RTSP connection closed by server.");
    goto disconnect;

 disconnect:
    ev_unloop(loop, EVUNLOOP_ONE);
}
Beispiel #2
0
int RtspServer(RTSP_buffer *rtsp)
{
	fd_set rset,wset;       /*读写I/O描述集*/
	struct timeval t;
	int size;
	static char buffer[RTSP_BUFFERSIZE+1]; /* +1 to control the final '\0'*/
	int n;
	int res;
	struct sockaddr ClientAddr;

#ifdef RTSP_DEBUG
//    fprintf(stderr, "%s, %d\n", __FUNCTION__, __LINE__);
#endif

//    memset((void *)&ClientAddr,0,sizeof(ClientAddr));

	if (rtsp == NULL)
	{
		return ERR_NOERROR;
	}

	/*变量初始化*/
	FD_ZERO(&rset);
	FD_ZERO(&wset);
	t.tv_sec=0;				/*select 时间间隔*/
	t.tv_usec=100000;

	FD_SET(rtsp->fd,&rset);

	/*调用select等待对应描述符变化*/
	if (select(g_s32Maxfd+1,&rset,0,0,&t)<0)
	{
		fprintf(stderr,"select error %s %d\n", __FILE__, __LINE__);
		send_reply(500, NULL, rtsp);
		return ERR_GENERIC; //errore interno al server
	}

	/*有可供读进的rtsp包*/
	if (FD_ISSET(rtsp->fd,&rset))
	{
		memset(buffer,0,sizeof(buffer));
		size=sizeof(buffer)-1;  /*最后一位用于填充字符串结束标识*/

		/*读入数据到缓冲区中*/
#ifdef RTSP_DEBUG
//    fprintf(stderr, "tcp_read, %d\n", __LINE__);
#endif
		n= tcp_read(rtsp->fd, buffer, size, &ClientAddr);
		if (n==0)
		{
			return ERR_CONNECTION_CLOSE;
		}

		if (n<0)
		{
			fprintf(stderr,"read() error %s %d\n", __FILE__, __LINE__);
			send_reply(500, NULL, rtsp);                //服务器内部错误消息
			return ERR_GENERIC;
		}

		//检查读入的数据是否产生溢出
		if (rtsp->in_size+n>RTSP_BUFFERSIZE)
		{
			fprintf(stderr,"RTSP buffer overflow (input RTSP message is most likely invalid).\n");
			send_reply(500, NULL, rtsp);
			return ERR_GENERIC;//数据溢出错误
		}

#ifdef RTSP_DEBUG
		fprintf(stderr,"INPUT_BUFFER was:%s\n", buffer);
#endif

		/*填充数据*/
		memcpy(&(rtsp->in_buffer[rtsp->in_size]),buffer,n);
		rtsp->in_size+=n;
		//清空buffer
		memset(buffer, 0, n);
		//添加客户端地址信息
		memcpy(	&rtsp->stClientAddr, &ClientAddr, sizeof(ClientAddr));

		/*处理缓冲区的数据,进行rtsp处理*/
		if ((res=RTSP_handler(rtsp))==ERR_GENERIC)
		{
			fprintf(stderr,"Invalid input message.\n");
			return ERR_NOERROR;
		}
	}

	/*有发送数据*/
	if (rtsp->out_size>0)
	{
		//将数据发送出去
		n= tcp_write(rtsp->fd,rtsp->out_buffer,rtsp->out_size);
		printf("5\r\n");
		if (n<0)
		{
			fprintf(stderr,"tcp_write error %s %i\n", __FILE__, __LINE__);
			send_reply(500, NULL, rtsp);
			return ERR_GENERIC; //errore interno al server
		}

#ifdef 	RTSP_DEBUG
		//fprintf(stderr,"OUTPUT_BUFFER length %d\n%s\n", rtsp->out_size, rtsp->out_buffer);
#endif
		//清空发送缓冲区
		memset(rtsp->out_buffer, 0, rtsp->out_size);
		rtsp->out_size = 0;
	}


	//如果需要RTCP在此出加入对RTCP数据的接收,并存放在缓存中。
	//继而在schedule_do线程中对其处理。
	//rtcp控制处理,检查读入RTCP数据报


	return ERR_NOERROR;
}