udp socket: 简单的数据包与视频流传输

标签: socket 视频流 数据 udp vlc
5854人阅读 评论(6) 收藏 举报
分类:

简单的包传输

客户端向服务端发送数据包,服务端打印出来。
我们来传送一首诗吧,柳永的《雨霖铃》
服务端:

#include <stdio.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <string.h>
#include <netinet/in.h>
#include <unistd.h>
#include <stdlib.h>
#include <arpa/inet.h>
#define PORT 24000

int main(){ 
    int s=socket(AF_INET,SOCK_DGRAM,0);
    if(s==-1){
        perror("create socket error: ");
        exit(1);
    }
    struct sockaddr_in serv,client;
    bzero(&serv,sizeof(serv));
    serv.sin_family=AF_INET;   
    serv.sin_addr.s_addr=inet_addr("10.21.100.153");// targe IP  
    serv.sin_port=htons(PORT);  
    if(bind(s,(struct sockaddr*)&serv,sizeof(serv))==-1){
        perror("bind error: ");
        exit(1);
    }
    int count = 0;
    char *buff = (char *)malloc(100);
    while(count < 10){
        int addr_len = sizeof(client);
        memset(buff,0,100);
        int ret = recvfrom(s,buff,100,0,(struct sockaddr *)&client,&addr_len); 
        if(ret == -1){
            perror("recvfrom error: ");
            exit(1);
        }
        else {
            count++;
            printf("%s\n",buff);
        }
    }
    close(s);
    if(buff) free(buff);
    return 0;
}

客户端:

#include <stdio.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <string.h>
#include <netinet/in.h>
#include <unistd.h>
#include <stdlib.h>
#include <arpa/inet.h>
#define PORT 24000

int main(){ 
        int s=socket(AF_INET,SOCK_DGRAM,0);
        if(s==-1){
             perror("create socket error: ");
             exit(1);
        }
        struct sockaddr_in serv;
        bzero(&serv,sizeof(serv));
        serv.sin_family=AF_INET;   
        serv.sin_addr.s_addr = inet_addr("10.21.100.153");    // targe IP 
        serv.sin_port=htons(PORT);
        char *buff = NULL;
        int i = 0;
        char str[10][80]={"雨霖铃","","寒蝉凄切,对长亭晚,骤雨初歇。","都门帐饮无绪,留恋处,兰舟摧发。",
            "执手相看泪眼,竟无语凝噎。","念去去千里烟波,暮霭沈沈楚天阔。","多情自古伤离别,更那堪冷落清秋节。",
        "今宵酒醒何处,杨柳岸、晓风残月。","此去经年,应是良辰好景虚设。","便纵有千种风情,更与何人说。"};
        while(i < 10){
             buff = str[i];
             sendto(s,buff,strlen(buff),0,(struct sockaddr *)&serv,sizeof(serv));
             sleep(1);
             i++;
        }
        close(s);
        buff = NULL;
        return 0;
}
./client
./server
雨霖铃

寒蝉凄切,对长亭晚,骤雨初歇。
都门帐饮无绪,留恋处,兰舟摧发。
执手相看泪眼,竟无语凝噎。
念去去千里烟波,暮霭沈沈楚天阔。
多情自古伤离别,更那堪冷落清秋节。
今宵酒醒何处,杨柳岸、晓风残月。
此去经年,应是良辰好景虚设。
便纵有千种风情,更与何人说。

视频传输

现在,我们用vlc传输视频给一个IP,然后转发给另一个IP。这就类似于给一台服务器传视频,服务器转发给终端。
vlc发送视频:
媒体——打开多个文件——添加,选择视频——流——下一步——new destination, UDP——添加,填写IP和相应的端口——profile, video-H.264+MP3(TS)——下一步——stream all elementary streams——stream
接收:
窗口:打开网络串流–填写udp://@:port
命令行: vlc udp://@IP:port 或者 vlc udp://@:port

type IP Port
转发端 10.21.100.152 5000
接收端 10.21.100.153 24000

code:

#include <stdio.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <string.h>
#include <netinet/in.h>
#include <unistd.h>
#include <stdlib.h>
#include <arpa/inet.h>
#include <signal.h>
#define PORT1 5000
#define PORT2 24000
void stop(int sig){
    puts("finish data transfer.");
    exit(0);
}
int main(){ 
    signal(SIGINT,stop);
    struct sockaddr_in serv1, serv2, client;
    bzero(&serv1,sizeof(serv1));
    serv1.sin_family=AF_INET;   
    serv1.sin_addr.s_addr=inet_addr("10.21.100.152");// serv1 used to recv data and transfer.
    serv1.sin_port=htons(PORT1);  
    int fd1 = socket(AF_INET,SOCK_DGRAM,0);
    if(fd1 == -1){
        perror("create socket fd1 error: ");
        exit(1);
    }
    if(bind(fd1,(struct sockaddr*)&serv1,sizeof(serv1))==-1){
        perror("bind serv1 ");
        exit(1);
    }
    bzero(&serv2,sizeof(serv2));
    serv2.sin_family=AF_INET;   
    serv2.sin_addr.s_addr=inet_addr("10.21.100.153");// serv2 used to recv data for vlc display.
    serv2.sin_port=htons(PORT2);  

    void *buff = malloc(1500); // vlc number of data bits is 1316
    while(1){
        int addr_len = sizeof(client);
        memset(buff,0,1500);
        int ret = recvfrom(fd1,buff,1500,0,(struct sockaddr *)&client,&addr_len); 
        printf("%5d ",ret);
        if(ret == -1){
           perror("recvfrom error: ");
           exit(1);
        }
        else {
           //ret = sendto(fd1,buff,strlen(buff),0,(struct sockaddr *)&serv2,sizeof(serv2)); // not fd2
           ret = sendto(fd1,buff,ret,0,(struct sockaddr *)&serv2,sizeof(serv2)); // not fd2
           printf("%5d\n",ret);
           if(ret == -1){
               perror("sendto error: ");
               exit(1);
           } 
        }
    }
    return 0;
}

效果:
这里写图片描述
这里写图片描述
注意:在sendto()中的字节数参数,不要用strlen(buff),最好使用recvfrom()的返回值。
我们可以打印一些重要的信息来查看内存情况。
code:

#include <stdio.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <string.h>
#include <netinet/in.h>
#include <unistd.h>
#include <stdlib.h>
#include <arpa/inet.h>
#include <signal.h>
#define PORT1 5000
#define PORT2 24000
void stop(int sig){
    puts("\n finish data transfer.");
    exit(0);
}
int main(){ 
    signal(SIGINT,stop);
    struct sockaddr_in serv1, serv2, client;
    bzero(&serv1,sizeof(serv1));
    serv1.sin_family=AF_INET;   
    serv1.sin_addr.s_addr=inet_addr("10.21.100.152");// serv1 used to recv data and transfer.
    serv1.sin_port=htons(PORT1);  
    int fd1 = socket(AF_INET,SOCK_DGRAM,0);
    if(fd1 == -1){
        perror("create socket fd1 error: ");
        exit(1);
    }
    if(bind(fd1,(struct sockaddr*)&serv1,sizeof(serv1))==-1){
        perror("bind serv1 ");
        exit(1);
    }
    bzero(&serv2,sizeof(serv2));
    serv2.sin_family=AF_INET;   
    serv2.sin_addr.s_addr=inet_addr("10.21.100.153");// serv2 used to recv data for vlc display.
    serv2.sin_port=htons(PORT2);  

    void *buff = malloc(1500); // vlc data length is 1316
    while(1){
        int addr_len = sizeof(client);
        memset(buff,0,1500);
        int ret = recvfrom(fd1,buff,1500,0,(struct sockaddr *)&client,&addr_len); 
        int i,j;
        int zero = 0;
        for(i=0;i<100;i++){  //look at memory
            for(j=0;j<15;j++){
                printf("0x%x ",*((char *)(buff)+i*15+j));
                if(*((char *)(buff)+i*15+j) == 0){
                    zero++;
                }
            }
            puts("");
        }
        printf("\n zero: %d \n",zero); // zero counts
        printf("%5d ",ret); //recv bits
        if(ret == -1){
           perror("recvfrom error: ");
           exit(1);
        }
        else {
           //ret = sendto(fd1,buff,strlen(buff),0,(struct sockaddr *)&serv2,sizeof(serv2)); 
           printf("%5d\n",strlen(buff)); //strlen calculate bits
           ret = sendto(fd1,buff,ret,0,(struct sockaddr *)&serv2,sizeof(serv2)); 
           sleep(1);
           if(ret == -1){
               perror("sendto error: ");
               exit(1);
           } 
        }
    }
    return 0;
}

log:

0x47 0x40 0x42 0x32 0xffffff90 0x0 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 
0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff 
...
...
...
0x7 0xffffffed 0x26 0x62 0xfffffff3 0x76 0xffffff8b 0x57 0xffffffab 0xffffffcf 0x5 0xffffffa7 0xffffffba 0xffffff80 0xffffffb2 
0x68 0xffffffa5 0xffffffb6 0x1b 0x5d 0x10 0xffffff83 0xffffffcc 0xffffffd5 0xffffffb6 0xffffffb8 0xffffff81 0xffffffa7 0x70 0xffffffe5 
0xffffff8b 0x2a 0x7c 0x33 0x51 0x59 0xffffffe4 0xffffffe6 0x32 0xffffff88 0x76 0xffffff94 0x48 0xffffff95 0xffffffde 
0x39 0xffffff94 0xffffffac 0x33 0x33 0x9 0x6b 0x6e 0xffffff9b 0x6f 0xfffffff3 0x0 0x0 0x0 0x0 
0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 
0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 
0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 
0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 
0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 
0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 
0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 
0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 
0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 
0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 
0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 
0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 

 zero: 229 
 1316     5 

因为接收到的数据不是连续填充的,(注意看第一行前六位),
0x47 0x40 0x42 0x32 0xffffff90 0x0
所以用strlen()得到的结果是远远小于recv的字节数的。如果使用sendto(fd1,buff,strlen(buff),0,(struct sockaddr *)&serv2,sizeof(serv2))转发的数据是很少的。

查看评论

基于UDP协议的简单基本视频传输程序的编写

一、UDP协议 UDP是User Datagram Protocol的简称,中文名是用户数据报协议,是OSI参考模型中一种无连接的传输层协议。正式通信前不必与对方先建立连接,直接向接收方发送数据,是一...
  • jhh_move_on
  • jhh_move_on
  • 2013年06月18日 10:57
  • 19923

使用FEC改善UDP(RTP)音视频传输效果

实时音视频领域UDP才是王道               在 Internet 上进行音视频实时互动采用的传输层方案有TCP(如:RTMP)和UDP(如:RTP)两种。TCP协议能为两个端点间的数据传...
  • mediapro
  • mediapro
  • 2015年12月24日 12:33
  • 10179

udp socket: 简单的数据包与视频流传输

简单的包传输客户端向服务端发送数据包,服务端打印出来。 我们来传送一首诗吧,柳永的《雨霖铃》 服务端:#include #include #include #include #includ...
  • theArcticOcean
  • theArcticOcean
  • 2016年09月25日 10:35
  • 5854

基于UDP的用于视频应用的几个协议

TCP由于其协议为保证可靠性,如三次握手,导致其比较慢,不能支持交互视频,会议等实时服务。UDP虽然是一个不可靠协议,不支持丢包重传,但是UDP可以根据端口号对应用程序进行多路复用,并能利用校验和检查...
  • u014571011
  • u014571011
  • 2016年11月09日 21:41
  • 1155

UDP协议的视频图像传输

  • 2013年01月03日 11:38
  • 365KB
  • 下载

基于UDP协议的简单基本视频传输程序的编写

一、UDP协议 UDP是User Datagram Protocol的简称,中文名是用户数据报协议,是OSI参考模型中一种无连接的传输层协议。正式通信前不必与对方先建立连接,直接向接收方发送数据,是...
  • u010457344
  • u010457344
  • 2014年03月30日 19:13
  • 646

C# 基于socket的UDP视频局域网传输

问题: 1;为什么选用UDP而非TCP?      TCP,UDP是运输层两种重要的通信协议,向上层的应用层提供通信服务,同时也向下屏蔽了网络通信的细节。      TCP较为复杂,是面向有连接...
  • ilipan
  • ilipan
  • 2015年04月10日 17:49
  • 3176

gstreamer学习笔记:通过udp传输音视频

(1)发送端: gst-launch -v gstrtpbin name=rtpbin latency=100 uridecodebin uri=file:///xxx/mux.avi name=de...
  • u010312436
  • u010312436
  • 2016年12月05日 15:07
  • 1658

H.264视频流的传输与载荷

从摄像头获取的视频数据,经过编码后(当然,也可以不编码,如果你觉得也很ok的话),既可以视频录制,同时如果需要,当然也可以视频远程传输咯,而实时传输协议(Real-time Transport Pr...
  • bytxl
  • bytxl
  • 2015年12月24日 11:17
  • 1269

视频流传输协议RTP/RTCP/RTSP/HTTP的区别

用一句简单的话总结:RTSP发起/终结流媒体、RTP传输流媒体数据 、RTCP对RTP进行控制,同步。 之所以以前对这几个有点分不清,是因为CTC标准里没有对RTCP进行要求,因此在标准RTSP的代...
  • i_lovefish
  • i_lovefish
  • 2015年08月22日 16:01
  • 2749
    个人资料
    持之以恒
    等级:
    访问量: 37万+
    积分: 9420
    排名: 2417
    我的链接
    最新评论