由于socket在传输时,是对socket文件描述符进行写和读,所以在发送端只需把要保存到文件中的数据写进socket文件里,在接收端只需从socket文件中读去数据就行了。流程如下:
接收端:(server)
创建socket->listen->accept->read(recv)->
decode->display
发送端: (client)
创建socket->connect->capture->encode->write(send)
需要说明的是,上面的流程图只是概念的说明,写、读和编、解码是在一个线程函数里的,为了将来和音频一起传输,视频部分是线程执行。部分程序代码如下:
接收端:(server)
1、main函数功能:
client_fd=receive_init(&server_fd,port);
pthread_create(&dec_tid,NULL, (void *)decode,
(void *)&arg);
2、 receive_init函数代码:
int
receive_init(int *sock_fd,int port)
{ struct
sockaddr_in server_addr;
int temp_sock_fd;
int err;
err=*sock_fd= socket(AF_INET,SOCK_STREAM,0);
if (err==-1){
perror(”socket”);
return -1;
}
server_addr.sin_family=AF_INET;
server_addr.sin_port=htons(port);
server_addr.sin_addr.s_addr=INADDR_ANY;
err=bind(*sock_fd,(struct sockaddr *)&
server_addr,sizeof(server_addr));
if(err==-1){
printf(”socket bind failed!\n”);
return -1;
}
err=listen(*sock_fd,2);
if (err==-1){
printf(”socket listen failed!\n”);
}
temp_sock_fd=accept(* sock_fd,(struct sockaddr *)NULL,NULL);
return temp_sock_fd;
}
3、decode函数比较复杂,大致内容:配置、申请bitstream空间、接受数据、解码、显示
发送端(client):
1、main函数功能:
pthread_create(&enc_tid,NULL,(void *)encode, (void
*)&arg);
2、send_init函数代码
int
send_init(int *sock_fd,char *host_addr,int port)
{
int err;
struct sockaddr_in server_addr;
server_addr.sin_family=AF_INET;
server_addr.sin_port=htons(port);
server_addr.sin_addr.s_addr=inet_addr(host_addr);
*sock_fd=socket(AF_INET,SOCK_STREAM,0);
err=connect(*sock_fd,(struct sockaddr *)&
server_addr,sizeof(server_addr));
if (err==-1){
perror(”connect”);
return -1;
}
return 0;
}
3、encode代码依然很复杂,基本内容:配置、申请bitstream空间、捕获、编码、发送数据
开头提到的延迟和停顿的问题的原因是,在接收端读数据的时候,每次实际上都读了很大很大的值,也即readn(int
socket_fd, void *buff, int size)
第三个参数size取得太大,每次都会花很长的时间去读很小的数据,最后把size改成比发送端writen所发送的size稍大一些。汗啊。。。都是因为视频部分太依赖测试代码了,自己没有好好想清楚!
原文出处:http://www.isongzi.com/2009/04/13/socket-video/