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

📄 dxc.c

📁 linux下多线程网络编程
💻 C
字号:
//多线程成功实例#include <strings.h>#include <stdio.h>#include <unistd.h>#include <stdlib.h>#include <errno.h>#include <stdarg.h>#include <linux/types.h>
#include <linux/videodev.h>#include <pthread.h>#include <semaphore.h>#include <sys/types.h>#include <sys/mman.h>#include <sys/ioctl.h>#include <sys/stat.h>#include <sys/time.h>#include <sys/file.h>#include <sys/stat.h>#include <fcntl.h>#include <time.h>#include <string.h> #include <netdb.h>#include <arpa/inet.h>#include <sys/times.h>#include <netinet/in.h>#include <sys/socket.h>#include <sys/param.h>#include <ctype.h>#include <sys/utsname.h>#define BUFSIZE  6#define DATA     32*1024#define PORT     5000
#define RTP_HDR_SZ 12
#define VIDEO_PALETTE_JPEG 21
 
unsigned char buf[BUFSIZE+2][DATA];
int head,tail;

sem_t writen;
sem_t readn;struct ARG{int sockfd; int sin_size; struct sockaddr_in client;
};
struct FDG{
int video_fd;
};
typedef unsigned char  u_int8;
typedef unsigned short u_int16;
int get_jpegsize (unsigned char *buf, int insize);double tdbl(struct timeval *a);
pthread_mutex_t  buffer_mutex=PTHREAD_MUTEX_INITIALIZER;

static void *producer(void *fdg)
{  struct FDG *vd;
 int video_fd;   if(sizeof(fdg)!=sizeof(struct FDG))  {    perror("producer arg error");    exit(1);   }  else   {
  vd=(struct FDG *)fdg;
  video_fd=vd->video_fd;
  free(fdg);  fdg=NULL;  }  
  for( ; ; )  {
         sem_wait(&writen);//减少可读的资源数
         pthread_mutex_lock(&buffer_mutex);//进入互斥区       // memset(buf[head], 's', 20);          read(video_fd, buf[head], DATA);
         head=(head+1) % BUFSIZE;
                 pthread_mutex_unlock(&buffer_mutex);//离开互斥区
         sem_post(&readn);//增加可读资源数
        // sleep(0.0001);
  }}
static void *consumer(void *arg)
{   int sockfd;  int sin_size;  int jpegsize;  struct sockaddr_in client;  struct ARG *info;    typedef struct {
    unsigned int version:2;   /* protocol version */
    unsigned int p:1;         /* padding flag */
    unsigned int x:1;         /* header extension flag */
    unsigned int cc:4;        /* CSRC count */
    unsigned int m:1;         /* marker bit */
    unsigned int pt:7;        /* payload type */
    unsigned int seq:16;      /* sequence number */
    unsigned int ts;               /* timestamp */
    unsigned int ssrc;             /* synchronization source */
  } rtp_hdr_t;   struct timeval start;     rtp_hdr_t rtphdr;  u_int8 *jpeg_data;
  u_int8 *packet_buf;  unsigned int  ts;  unsigned int ssrc;  u_int8 *ptr;  u_int8 frame,bframe;  int bytes_left ;//jpeg数据总长度  int data_len,packetsize;//packetsize变量   info=( struct ARG *)arg;  if(info->sockfd<0)  {     perror("error error");    exit(1);  }    if(info->sin_size!=16)  {     perror("err error");    exit(1);  }  sockfd=info->sockfd;  sin_size=info->sin_size;  memcpy(&client,&info->client,sizeof(info->client));  free(arg);
  arg=NULL;    packetsize=RTP_HDR_SZ+2050;  packet_buf = (u_int8 *)calloc(packetsize, sizeof(u_int8));  jpeg_data= (u_int8 *) malloc(DATA);

  for(;;)  {    frame=0;
    gettimeofday(&start, 0);    ts = (unsigned int)(tdbl(&start)*1000);    ssrc = 125;    /* Initialize RTP header*/       rtphdr.version = 2;    rtphdr.p = 0;    rtphdr.x = 0;    rtphdr.cc = 0;    rtphdr.m = 0;    rtphdr.pt = 40;    rtphdr.seq = 1;    rtphdr.ts = htonl(ts);    rtphdr.ssrc = htonl(ssrc);
         sem_wait(&readn);//减少可读的资源数         
         pthread_mutex_lock(&buffer_mutex);//进入互斥区                  jpegsize=get_jpegsize(buf[tail],DATA);        
         if(jpegsize!=-1)          {
            memcpy(jpeg_data,buf[tail],jpegsize);
          }                  tail=(tail+1) % BUFSIZE;                pthread_mutex_unlock(&buffer_mutex);//离开互斥区       
         sem_post(&writen);//增加可读资源数     bytes_left = jpegsize;      
    while (bytes_left > 0) 
  {    ptr = packet_buf + RTP_HDR_SZ;       bframe=frame;      data_len = packetsize - (ptr - packet_buf)-2;//每一分片大小    if (data_len >= bytes_left)   //当为最后一个分片时    {      data_len = bytes_left;      rtphdr.m = 1;      bframe=255;      data_len=jpegsize%2048;    }       *ptr=bframe;  ptr++;   *ptr=frame;   ptr++;       rtphdr.seq = htons(rtphdr.seq);    memcpy(packet_buf, &rtphdr, RTP_HDR_SZ);    memcpy(ptr, jpeg_data + frame*2048, data_len);       if(sendto(sockfd,packet_buf,(ptr - packet_buf) + data_len,0,(struct sockaddr *)&client,sin_size)<0)     {       perror(" sendto error");       }         frame++;    bytes_left -= 2048;    rtphdr.seq = ntohs(rtphdr.seq);    rtphdr.seq++;  }       
       sleep(0.0001);    
  }  free(packet_buf);  free(jpeg_data);  pthread_exit(NULL);}
int main()
{
  clock_t oldtick,newtick;  float time1 ;  static int vf=0;  int i;  clock_t totalold,totalnew;  int video_fd;  struct video_capability grab_cap;  int width = 320;  int height = 240;  struct video_picture grab_pic;  struct video_mmap grab_map;  struct video_mbuf grab_buf;

  int sockfd;  int sin_size;  struct sockaddr_in client;
  struct sockaddr_in server;  char msg[100];  struct ARG *arg;   struct FDG  *fdg;
  pthread_t p_tid;
  pthread_t c_tid;  head=0;  tail=0;  for(i=0; i<BUFSIZE+2; i++)  {     bzero(buf[i],DATA);      }  sem_init(&writen,0,BUFSIZE);
  sem_init(&readn,0,0);

//数据采集……………………………………………………………………………loop: totalold = clock(); video_fd = open("/dev/video0", O_RDWR); if (video_fd == -1)  {   fprintf(stderr, "can not open video0");//\u6253\u5f00\u6444\u50cf\u5934   exit(1); } oldtick = clock(); if ((ioctl(video_fd, VIDIOCGCAP, &grab_cap)) < 0)  {   fprintf(stderr, "ioctl VIDEOCGCAP failed.");   exit(1); } newtick = clock(); time1 = (double)(newtick - oldtick)/ CLOCKS_PER_SEC; printf("\n%f second is take to ioctl VIDEOCGCAP \n",time1);printf("The VideoCap Name: %s\n", grab_cap.name);printf("The hannels: %d\n", grab_cap.channels);printf("The Audios: %d\n", grab_cap.audios);printf("The maxwidth: %d, maxheight: %d, minwidth %d, minheight: %d\n",grab_cap.maxwidth, grab_cap.maxheight, grab_cap.minwidth, grab_cap.minheight); oldtick = clock();if ((ioctl(video_fd, VIDIOCGPICT, &grab_pic)) < 0) {  fprintf(stderr, "ioctl VIDIOCGPICT failed.");  exit(1);} newtick = clock(); time1 = (double)(newtick - oldtick)/ CLOCKS_PER_SEC; printf("\n%f second is take to ioctl VIDIOCGPICT \n",time1);printf("The brightness: %d\nThe hue: %d\nThe colour: %d\nThe contrast:%d\nThe whiteness: %d\nThe depth: %d\nThe palette: %d\n", grab_pic.brightness, grab_pic.hue, grab_pic.colour, grab_pic.contrast, grab_pic.whiteness, grab_pic.depth, grab_pic.palette); oldtick = clock();if ((ioctl(video_fd, VIDIOCGMBUF, &grab_buf)) < 0) {  fprintf(stderr, "ioctl VIDIOCGMBUF, failed.");  exit(1);} newtick = clock(); time1 = (double)(newtick - oldtick)/ CLOCKS_PER_SEC; printf("\n%f second is take to ioctl VIDIOCGMBUF \n",time1);printf("The mapping size: %d\nThe mapping frames: %d\nThe mapping offset %d\n",grab_buf.size, grab_buf.frames, grab_buf.offsets);printf("The mapping size: %d  nihao\n",grab_buf.size);grab_map.width = width;grab_map.height = height;grab_map.format = VIDEO_PALETTE_JPEG;grab_map.frame = 0;if(vf==0){  vf=vf+1;  close(video_fd);  goto loop;}
fdg=(struct FDG *)malloc(sizeof(struct FDG));if(fdg==NULL){   perror("fdg malloc error");  exit(1); } else  {fdg->video_fd=video_fd;}

if(pthread_create(&p_tid, NULL, producer, (void *)fdg)){   perror("pthrea p_tid1 error!");   exit(1);}
  // free(fdg);  // fdg=NULL;//网络部分if((sockfd=socket(AF_INET,SOCK_DGRAM,0))==-1){perror("creat socket error");exit(1);}bzero(&server,sizeof(server));server.sin_family=AF_INET;server.sin_port=htons(PORT);server.sin_addr.s_addr=htonl(INADDR_ANY);if(bind(sockfd,(struct sockaddr *)&server,sizeof(struct sockaddr))==-1){perror("bind error");exit(1);}sin_size=sizeof(struct sockaddr_in);        while(1)  {        if((recvfrom(sockfd,msg,100,0,(struct sockaddr *)&client,&sin_size))<0)    {         perror("recv error");          exit(1);     }        arg=(struct ARG *)malloc(sizeof(struct ARG));  if(arg==NULL)  {    perror("ARG malloc error");    exit(1);   }  else {         arg->sockfd=sockfd;		 arg->sin_size=sin_size;		 memcpy((void *)&arg->client,&client,sizeof(client));		}   
 if(pthread_create(&c_tid,NULL,consumer,(void *)arg)) {  perror("pthread c_tid error!");   exit(1); }  // free(arg);  // arg=NULL;     }  
pthread_join(p_tid,NULL);//pthread_join(p_tid2,NULL);
pthread_join(c_tid,NULL);
close(video_fd);close(sockfd);return 0;}
   
   //获得JPEG图片大小int get_jpegsize (unsigned char *buf, int insize){ int i,flg=0,fc=0,fd=0,nd=0,k;  
  if((buf[0]== 0xFF) && (buf[1] == 0xD8)&& (buf[2]== 0xFF) && (buf[3] == 0xDB))	  {            for ( k= 0 ; k< 590; k++)         {           if(buf[k]== 0x0D)nd++;                    if ((buf[k]== 0xFF) && (buf[k+1] == 0xC4))           {               flg++;               fc=k+1;           } 	      if ((buf[k]== 0xFF) && (buf[k+1] == 0xDA))  	      { 	           fd=k+1;               flg++; 	           break; 	       } 	          	     } 	    if((flg==2)&&(fc==137)&&(fd==576)&&(nd<=5))   {               for ( i= 1024*2 ; i< insize; i++)      { 	    if ((buf[i] == 0xFF) && (buf[i+1] == 0xD9)) return i+2;      }
       }
  } return -1;}double tdbl(struct timeval *a){  return a->tv_sec + a->tv_usec/1e6;}

⌨️ 快捷键说明

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