udp socket: 简单的数据包与视频流传输
2016-09-25 10:35
162 查看
简单的包传输
客户端向服务端发送数据包,服务端打印出来。我们来传送一首诗吧,柳永的《雨霖铃》
服务端:
#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 |
#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协议的简单基本视频传输程序的编写
- Linux C raw socket 发送ipv4下的简单udp数据包
- 基于UDP协议的简单基本视频传输程序的编写
- 基于UDP协议的简单基本视频传输程序的编写
- (视频相关)Android手机间通过Socket,Udp实时传输视频
- C# 基于socket的UDP视频局域网传输
- [置顶] 基于iOS的网络音视频实时传输系统(四)- 自定义socket协议(TCP、UDP)
- socket编程(三)---- UDP协议与传输数据报文
- [转] 最简单的使用UDP通信的Python Socket例子
- socket 传输文件(简单)
- linux简单的TCP与UDP的socket程序以及机器大小端的判断程序
- socket编程——TCP/UDP数据传输
- linux下视频采集服务器(UDP传输、多线程模式)
- C#实现Socket传输简单数据
- 有关socket通信包大小的问题总结(UDP传输模式)
- socket编程——TCP/UDP数据传输
- [gcc编程] socket编程——TCP/UDP数据传输
- 两个线程,一音/一视频udp数据包,优先级问题,在线等!
- UNIX环境高级编程学习之第十六章网络IPC:套接字 - 简单UDP Socket 通信
- 已解决:Linux中用socket实现视频、音频的同步传输