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

📄 network.c

📁 linux下流媒体下载程序代码
💻 C
📖 第 1 页 / 共 2 页
字号:
    }    else { /* default IPv4 */	inet_ntop(result->ai_family,		  &((struct sockaddr_in *)result->ai_addr)->sin_addr,		  hoststr,		  sizeof(hoststr));    }        /* display host:ports */    display(MSDL_NOR,"Host: [ %s:%s ]  ",hoststr,portstr);            sock_server = socket(result->ai_family,result->ai_socktype,result->ai_protocol);      if(sock_server == -1) {	display(MSDL_ERR,"socket() error");	return -1;    }        /* Turn the socket to non-blocking socket, so we can timeout. */    fcntl(sock_server,F_SETFL,fcntl(sock_server,F_GETFL) | O_NONBLOCK);        if(connect(sock_server,result->ai_addr,result->ai_addrlen) == -1) {	/* failed not because it was non-blocking */	if(errno != EINPROGRESS) {	    display(MSDL_ERR,"connect() failed");	    goto failed;	}    }      for(;;) {    	/* init */	tv.tv_sec = 3;	tv.tv_usec = 0;	FD_ZERO(&set);	FD_SET(sock_server,&set);		ret = select(sock_server+1,NULL,&set,NULL,&tv);	if(ret < 0) { /* select failed! */	    display(MSDL_ERR,"select() failed");	    goto failed;	}	else if(ret > 0) break;	else if(try_count > 5) { /* 12 sec */	    display(MSDL_ERR,"timeout!\n");	    goto failed;	}    	display(MSDL_NOR,".");	try_count++;    }      /* Turn the socket to blocking, as we don't need it. */    fcntl(sock_server, F_SETFL, fcntl(sock_server,F_GETFL) & ~O_NONBLOCK);      display(MSDL_NOR,"  connected!\n");        freeaddrinfo(result);    return sock_server;        /* failure */  failed:    if(sock_server) close(sock_server);    if(result) freeaddrinfo(result);    return -1;}/* * prepare listning socket opening 'port'. * protocol family can be specified by 'family' * *           return value :       sock ... success *                                  -1 ... failure */int waiting_socket(int family,int port){    int sock;    int ret;    char portstr[8];    struct addrinfo hints,*result = NULL;        if(port < 0 || 0xffff < port) {	display(MSDL_ERR,"internal: invalid port number\n");	goto failed;    }        memset(portstr,0,8);    snprintf(portstr,7,"%d",port);        memset(&hints,0,sizeof(hints));    hints.ai_family = family;    hints.ai_socktype = SOCK_STREAM;    hints.ai_flags = AI_PASSIVE;        ret = getaddrinfo(NULL,portstr,&hints,&result);    if(ret != 0) {	perror("getaddrinfo() failed");	goto failed;    }    sock = socket(result->ai_family,result->ai_socktype,result->ai_protocol);    if(sock < 0) {	perror("socket() failed");	goto failed;    }        ret = bind(sock,(struct sockaddr *)result->ai_addr,result->ai_addrlen);    if(ret < 0) {	perror("bind() failed");	goto failed;    }        ret = listen(sock,1);    if(ret < 0) {	perror("listen() failed");	goto failed;    }    freeaddrinfo(result);    return sock;      failed:    if(result) freeaddrinfo(result);    return -1;}/* * accept connectoin from client. * return value :         sock .. success *                          -1 .. failure */int accept_connection(int wait_sock){    struct sockaddr_storage ss;    socklen_t sslen;    int sock;    int ret;        ret = sock_check_data(wait_sock,15);    if(ret <= 0) {	return -1;    }        sslen = sizeof(ss);    sock = accept(wait_sock,(struct sockaddr *)&ss,&sslen);    if(sock == -1) {	perror("accept() failed");	return -1;    }    return sock;}/* * this is wrapper for recv, and has timeout. * return value:            length --> success *                              -1 --> error/timeout *                               0 --> eof */int xrecv(int sock,void *buf,size_t count){    fd_set fds;    struct timeval tv;    int retval;      tv.tv_sec  = XRECV_TIMEOUT;    tv.tv_usec = 0;      FD_ZERO(&fds);    FD_SET(sock,&fds);    retval = select(sock + 1,&fds,NULL,NULL,&tv);    if(retval == -1) {  /* select() Error (system call error) */	perror("select() failed\n");	goto failed;    }    else if(!retval) {  /* No data arrived (error)*/	display(MSDL_ERR,"timeout!! could not receive data\n");	goto failed;    }    retval = recv(sock,buf,count,0);      if(retval < 0) {       /* recv()   Error (system call error) */	perror("recv() failed\n");	goto failed;    }    return retval;    failed:    return -1;}/* * send() wrapper */int xsend(int sock,void *buf,size_t count){    return (send(sock,buf,count,0));}int sock_check_data(int sock,int timeout){    fd_set fds;    struct timeval tv;    int ret;        FD_ZERO(&fds);    FD_SET(sock,&fds);    tv.tv_sec = timeout;    tv.tv_usec = 0;    ret = select(sock + 1,&fds,NULL,NULL,&tv);    if(ret == -1) {	perror("stream_check_data: select() failed");    }        return ret;}int stream_check_data(struct stream_t *stream,int timeout){    if(stream->netsock->data_len) {	return 1;    }        return sock_check_data(stream->netsock->sock,timeout);}/* * recv count bytes of data from sock to buf. * this is only used when count bytes of data are * supposed to come from sock. * this function must be used when 'count' bytes are guaranteed * to be received. *          return value: length --> success. *                        0      --> eof *                        -1     --> timeout or error (fatal) */int get_data(int sock,void *buf,size_t count){    int len;    size_t total = 0;      while(total < count) { /* more data to recv. */    	len = xrecv(sock,(uint8_t *)buf + total,count - total);    	if(len < 0) {       /* Error. timeout, syscall error */	    goto failed;	}	else if(len == 0) { /* EOF */	    display(MSDL_ERR,"met EOF when %d bytes are to come\n",count);	    goto meteof;	}    	total += len;    }      return total;    meteof:    return 0;    failed:    return -1;}/* * read 'size' bytes from *resources*. * *       *resources* are : [in this order] *                    1. netsock->buffer (data which came with http header) *                    2. netsock->sock   (network) * *               return value : size which read. *                              -1 if get_data failed. */int read_data(struct stream_t *stream, void *buffer, size_t size){    struct netsock_t *netsock = stream->netsock;    int len; /* how many bytes are stored in 'buffer' */    int ret;    /*printf("read_data size = %d   netsock->data_len = %d,"      " netsock->buffer_pos = %d\n",      size,netsock->data_len, netsock->buffer_pos);*/      len = 0;    if(netsock->data_len) {	/* there is a data to read in netsock->buffer */    	len = (size < netsock->data_len)	    ? size : netsock->data_len; /* smaller */    	memcpy((uint8_t *)buffer,netsock->buffer + netsock->buffer_pos,len);    	netsock->buffer_pos += len;	netsock->data_len -= len;    	if(netsock->data_len == 0) {	    netsock->buffer_pos = 0;	}    }      if(len < size) {	ret = get_data(netsock->sock,(uint8_t *)buffer + len, size - len);	if(ret < 0) { /* get_data mets timeout/error */	    return -1;	}	else {	    len += ret;	}    }      return len;}/* * different from read_data, this function's 3ed argument is  * max byte to read from stream. * return value:             len ... bytes stored in buffer *                             0 ...  *                            -1 ... timeout */int recv_data(struct stream_t *stream,void *buffer,size_t max){    struct netsock_t *netsock = stream->netsock;    int len; /* how many bytes are stored in 'buffer' */    int ret;      if((len = netsock->data_len)) {	/* there is a data to read in netsock->buffer */    	len = (max < len) ? max : len; /* smaller */    	memcpy((uint8_t *)buffer,netsock->buffer + netsock->buffer_pos,len);    	netsock->buffer_pos += len;	netsock->data_len -= len;    	if(netsock->data_len == 0) {	    netsock->buffer_pos = 0;	}    }      /* still network stream can be read. */    if(len < max) {	if(!len || sock_check_data(netsock->sock,0)) {/* just check there are some data now */	    ret = xrecv(netsock->sock,(uint8_t *)buffer + len,max - len);	    if(ret < 0) {		return -1;	    }	    else {		len += ret;		/*		  when sock was shut down by server and nothing was in buffer,		  len == 0 and ret == 0 so return 0, this is OK.		 */	    }	}    }    return len;}/* * push data to netsock->buffer so that the data can be read later */int stream_data_push_back(struct stream_t *stream,void *buffer,int size){    struct netsock_t *netsock = stream->netsock;      if(netsock->data_len) {	memmove(netsock->buffer + netsock->buffer_pos + size,		netsock->buffer + netsock->buffer_pos,		netsock->data_len);    }    memcpy(netsock->buffer + netsock->buffer_pos,buffer,size);    netsock->data_len += size;        return (netsock->data_len);}

⌨️ 快捷键说明

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