2019-11-11 21:42:26 dengjin20104042056 阅读数 529

00. 目录

01. 概述

UDP 是 User Datagram Protocol 的简称, 中文名是用户数据报协议,是一个简单的面向数据报的传输层协议,在网络中用于处理数据包,是一种无连接的协议。UDP 不提供可靠性的传输,它只是把应用程序传给 IP 层的数据报发送出去,但是并不能保证它们能到达目的地。由于 UDP 在传输数据报前不用在客户和服务器之间建立一个连接,且没有超时重发等机制,故而传输速度很快。

UDP 有如下的特点:

1)邮件系统服务模式的抽象(可通过邮件模型来进行对比)

2)每个分组都携带完整的目的地址

3)发送数据之前不需要建立链接

4)不对数据包的顺序进行检查,不能保证分组的先后顺序

5)不进行分组出错的恢复和重传

6)不保证数据传输的可靠性

在这里插入图片描述

在网络质量令人十分不满意的环境下,UDP 协议数据包丢失会比较严重。但是由于 UDP 的特性:它不属于连接型协议,因而具有资源消耗小,处理速度快的优点,所以通常音频、视频和普通数据在传送时使用 UDP 较多,因为它们即使偶尔丢失一两个数据包,也不会对接收结果产生太大影响。比如我们聊天用的 ICQ 和 QQ 就是使用的 UDP 协议。

02. UDP编程C/S结构

在这里插入图片描述

对于 UDP客户端编程流程,有点类似于写信过程:找个邮政工作人员( socket() )->信封上写上地址同时里面装上信件内容并且投递(sendto() )-> ……还可以继续写信,或者,接收对方的回信(recvfrom() )……-> 打完收工(close() )。

对于 UDP 服务器编程流程, 有点类似于收信过程:找个邮政工作人员( socket() ) -> 确定信箱的位置:地址+信箱号(bind() )-> 等待对方的来信( recvfrom() )-> ……还可以回信(write() ),或者,继续等待对方的来信……

UDP 服务器程序
UDP网络程序想要收取数据需什么条件?

1)确定的 ip 地址

2)确定的端口(port)

这正如,我要收到别人寄过来的信,我必须告诉别人我的地址(ip),同时告诉别人我我的公寓信箱号(端口)。

接收端使用 bind() 函数,来完成地址结构与 socket 套接字的绑定,这样 ip、port 就固定了,发送端在 sendto 函数中指定接收端的 ip、port,就可以发送数据了。

03. UDP常用函数

3.1 sendto函数

#include <sys/types.h>
#include <sys/socket.h>
ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
               const struct sockaddr *to, socklen_t addrlen);
功能:
	向 to 结构体指针中指定的 ip,发送 UDP 数据,可以发送 0 长度的 UDP 数据包
参数:
	sockfd:套接字
	buf:发送数据缓冲区
	len:发送数据缓冲区的大小
	flags:一般为 0
	to:指向目的主机地址结构体的指针
	addrlen:to 所指向内容的长度
返回值:
	成功:发送数据的长度
	失败: -1

3.2 recvfrom函数

#include <sys/types.h>
#include <sys/socket.h>
ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,
                 struct sockaddr *src_addr, socklen_t *addrlen);
功能:
	接收 UDP 数据,并将源地址信息保存在 from 指向的结构中,默认的情况下,
    如果没有接收到数据,这个函数会阻塞,直到有数据到来。
参数:
	sockfd:套接字
	buf:接收数据缓冲区
	len:接收数据缓冲区的大小
	flags:套接字标志(常为 0)
	from:源地址结构体指针,用来保存数据的来源
	addrlen:from 所指内容的长度
返回值:
	成功:接收到的长度
	失败: -1

3.3 bind函数

#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>

int bind(int sockfd, const struct sockaddr *addr,
         socklen_t addrlen);
功能:
	将本地协议地址与 sockfd 绑定,这样 ip、port 就固定了
参数:
	sockfd:socket 套接字
	addr: 指向特定协议的地址结构指针
	addrlen:该地址结构的长度
返回值:
	成功:返回 0
	失败:-1

参考示例:

// 本地网络地址
struct sockaddr_in my_addr;
bzero(&my_addr, sizeof(my_addr));	// 清空结构体内容
my_addr.sin_family = AF_INET;	// ipv4
my_addr.sin_port   = htons(port);	// 端口转换
// 绑定网卡所有ip地址,INADDR_ANY为通配地址,值为0
my_addr.sin_addr.s_addr = htonl(INADDR_ANY); 
 
printf("Binding server to port %d\n", port);
int err_log;
err_log = bind(sockfd, (struct sockaddr*)&my_addr, sizeof(my_addr)); // 绑定
if(err_log != 0)
{
	perror("bind");
	close(sockfd);		
	exit(-1);
}

04. 程序示例

4.1 UDP客户端

对比于写信模型,客户端相当于寄信人,要想成功给人寄信,信封上必须写上对方的地址。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
 
int main(int argc, char *argv[])
{
	unsigned short port = 8080;	//服务器端口
	char *server_ip = "192.168.12.10";	//服务器ip地址
	
	if( argc > 1 )	// main函数传参,服务器ip地址
	{	
		server_ip = argv[1];
	}
	
	if( argc > 2 )	// main函数传参,服务器端口
	{
		port = atoi(argv[2]);
	}
 
	int sockfd;
	sockfd = socket(AF_INET, SOCK_DGRAM, 0);   //创建UDP套接字
	if(sockfd < 0)
	{
		perror("socket");
		exit(-1);
	}
	
	// 套接字地址
	struct sockaddr_in dest_addr;
	bzero(&dest_addr, sizeof(dest_addr));	// 清空内容
	dest_addr.sin_family = AF_INET;		// ipv4
	dest_addr.sin_port   = htons(port);	// 端口转换
	inet_pton(AF_INET, server_ip, &dest_addr.sin_addr);	// ip地址转换
 
	printf("send data to UDP server %s:%d!\n", server_ip, port);
	
	while(1)
	{
		char send_buf[512] = "";
		fgets(send_buf, sizeof(send_buf), stdin);//获取输入
		send_buf[strlen(send_buf)-1] = '\0';
		//发送数据
		int len = sendto(sockfd, send_buf, strlen(send_buf), 0, 
                         (struct sockaddr*)&dest_addr, sizeof(dest_addr));
		printf("len = %d\n", len);
	}
	
	close(sockfd);
	return 0;
}

UDP客户端注意事项:

1)本地IP、本地端口(我是谁)

2)目的IP、目的端口(发给谁)

3)在客户端的代码中,我们只设置了目的IP、目的端口

4)客户端的本地 ip、本地 port 是我们调用 sendto 的时候 linux 系统底层自动给客户端分配的;分配端口的方式为随机分配,即每次运行系统给的 port 不一样。

4.2 UDP服务端

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
int main(int argc, char *argv[])
{
	unsigned short port = 8000;		// 本地端口
	if(argc > 1)
	{
		port = atoi(argv[1]);
	}
 
	int sockfd;
	sockfd = socket(AF_INET, SOCK_DGRAM, 0);	// 创建套接字
	if(sockfd < 0)
	{
		perror("socket");
		exit(-1);
	}
	
	// 本地网络地址
	struct sockaddr_in my_addr;
	bzero(&my_addr, sizeof(my_addr));	// 清空结构体内容
	my_addr.sin_family = AF_INET;	// ipv4
	my_addr.sin_port   = htons(port);	// 端口转换
	// 绑定网卡所有ip地址,INADDR_ANY为通配地址,值为0
	my_addr.sin_addr.s_addr = htonl(INADDR_ANY); 
	
	printf("Binding server to port %d\n", port);
	int err_log;
	err_log = bind(sockfd, (struct sockaddr*)&my_addr, sizeof(my_addr)); // 绑定
	if(err_log != 0)
	{
		perror("bind");
		close(sockfd);		
		exit(-1);
	}
	
	printf("receive data...\n");
	while(1)
	{
		int recv_len;
		char recv_buf[512] = "";
		struct sockaddr_in client_addr;
		char cli_ip[INET_ADDRSTRLEN] = "";//INET_ADDRSTRLEN=16
		socklen_t cliaddr_len = sizeof(client_addr); 
		
		// 接受数据
		recv_len = recvfrom(sockfd, recv_buf, sizeof(recv_buf), 0, 
							(struct sockaddr*)&client_addr, &cliaddr_len);
		inet_ntop(AF_INET, &client_addr.sin_addr, cli_ip, INET_ADDRSTRLEN);
		printf("\nip:%s ,port:%d\n",cli_ip, ntohs(client_addr.sin_port));
		printf("data(%d):%s\n",recv_len,recv_buf);
	}
	
	close(sockfd);
	return 0;
}

05. 附录

2013-05-26 14:59:36 gqb666 阅读数 12183

原创作品,转载时请务必以超链接形式标明文章原始出处:http://blog.csdn.net/gqb666/article/details/8970207,作者:gqb666

         接上篇博文Linux网络编程之使用TCP传输文件。最近在写Linux网络方面的demo,用UDP实现了一个简单的传输文件程序,适用于网卡设备及TCP/IP协议栈及网络环境测试时使用。当然这里要说的是,一般通过网络传输文件不会选择UDP协议,因为UPD提供不可靠的传输,文件传输过程中会出现丢包现象而导致文件传输错误。这里要实现UDP传输文件的目的是为了测试网卡的丢包率,然后与正常网络的丢包率进行比较,从而可以检验网卡及网络环境的质量。本文仅将其雏形写出。其功能是使用UDP协议从client端向server端传输文件,用法如下:

     编译:

           client:gcc -o client client.c

           server:gcc -o server server.c

     运行:

           client端:./client <server IP> <端口号> <上传文件名>

           server端:./server <端口号> <保存为文件名>

其中,server端先运行,client端与server端的端口号必须一致并且不能与已知端口冲突(例如8888即可)

下面将代码贴上:

server端代码:server.c

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

#define    FINISH_FLAG    "FILE_TRANSPORT_FINISH"
#define    MAXLINE        1024 

void usage(char *command)
{
    printf("usage :%s portnum filename\n", command);
    exit(0);
}
int main(int argc,char **argv)
{
    struct sockaddr_in     serv_addr;
    struct sockaddr_in     clie_addr;
    char                   buf[MAXLINE];
    int                    sock_id;
    int                    recv_len;
    int                    clie_addr_len;
    FILE                   *fp;

    if (argc != 3) {
        usage(argv[0]);
    }
	/* Create the the file commented by guoqingbo*/
    if ((fp = fopen(argv[2], "w")) == NULL) {
        perror("Creat file failed");
        exit(0);
    }
    if ((sock_id = socket(AF_INET,SOCK_DGRAM,0)) < 0) {
        perror("Create socket failed\n");
        exit(0);
    }
	/*fill the server sockaddr_in struct commented by guoqingbo*/  
    memset(&serv_addr,0,sizeof(serv_addr));
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_port = htons(atoi(argv[1]));
    serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);

    if (bind(sock_id,(struct sockaddr *)&serv_addr,sizeof(serv_addr)) < 0 ) {
        perror("Bind socket faild\n");
        exit(0);
    }
    /* server part commented by guoqingbo*/  
    clie_addr_len = sizeof(clie_addr);
    bzero(buf, MAXLINE); 
    while (recv_len = recvfrom(sock_id, buf, MAXLINE, 0,(struct sockaddr *)&clie_addr, &clie_addr_len)) {
        if(recv_len < 0) {
            printf("Recieve data from client failed!\n");
            break;
        }
        printf("#");
        if ( strstr(buf, FINISH_FLAG) != NULL ) {
            printf("\nFinish receiver finish_flag\n");
            break;
        }
        int write_length = fwrite(buf, sizeof(char), recv_len, fp);
        if (write_length < recv_len) {
            printf("File write failed\n");
            break;
        }
        bzero(buf, MAXLINE);
    }

    printf("Finish recieve\n");
    fclose(fp); 
    close(sock_id); 
    return 0;
}
client端代码:client.c

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

#define    FINISH_FLAG    "FILE_TRANSPORT_FINISH"
#define    MAXLINE        1024

void usage(char *command)
{
    printf("usage :%s ipaddr portnum filename\n", command);
    exit(0);
}
int main(int argc,char **argv)
{
    FILE                   *fp;
    struct sockaddr_in     serv_addr;
    char                   buf[MAXLINE];
    int                    sock_id;
    int                    read_len;
    int                    send_len;
    int                    serv_addr_len;
    int                    i_ret;
    int                    i;

    if (argc != 4) {
        usage(argv[0]);
    }
    /* open the file to be transported commanted by guoqingbo*/
    if ((fp = fopen(argv[3],"r")) == NULL) {
        perror("Open file failed\n");
        exit(0);
    }
    /* create the socket commanted by guoqingbo*/
    if ((sock_id = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
        perror("Create socket failed");
        exit(0);
    }
    memset(&serv_addr,0,sizeof(serv_addr));
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_port = htons(atoi(argv[2]));
    inet_pton(AF_INET, argv[1], &serv_addr.sin_addr);
    serv_addr_len = sizeof(serv_addr);
    /* connect the server commanted by guoqingbo*/
    i_ret = connect(sock_id, (struct sockaddr *)&serv_addr, sizeof(struct sockaddr));
    if (-1 == i_ret) {
        perror("Connect socket failed!\n");
        exit(0);
    }
    /* transport the file commented by guoqingbo*/
    bzero(buf, MAXLINE);
    while ( (read_len = fread(buf, sizeof(char), MAXLINE, fp)) > 0 ) {
        send_len = send(sock_id, buf, read_len, 0);
        if ( send_len < 0 ) {
            perror("Send data failed\n");
            exit(0);
        }
        bzero(buf, MAXLINE);
    }
    fclose(fp);
    /* send the end_flag commented by guoqingbo*/
    bzero(buf, MAXLINE);
    strcpy(buf, FINISH_FLAG);
    buf[strlen(buf)] = '\0';
    for (i = 1000; i>0; i--) {
        send_len = send(sock_id, buf, strlen(buf)+1, 0);
        if ( send_len < 0 ) {
            printf("Finish send the end string\n");
            break;
        }
    }
    close(sock_id);
    printf("Send finish\n");
    return 0;
}

上接博文: Linux网络编程之使用TCP传输文件

2016-08-04 21:28:59 Andoubi 阅读数 616

前一篇文章介绍了linux网络编程中的TCP编程:http://blog.csdn.net/andoubi/article/details/51778988,本文主要介绍UDP编程。

UDP编程模型如下图所示:


与TCP传输数据相比,UDP传输数据前不需要建立连接。

1、具体用到的函数如下:
服务器端:
创建socket: socket()   绑定地址:bind()  发/收数据:sendto()/recvfrom()  结束连接:close()
客户机端:
创建socket: socket()   发/收数据:sendto()/recvfrom()  结束连接:close()

2、涉及函数详解:

与TCP编程相比,UDP编程知识数据的发送接收函数有变化,其它函数都是一样的。这里就介绍一些数据的发送接收函数。

2.1数据发送函数:sendto函数


destaddr是接收端套接字的地址。使用sendto函数发送数据,必须指定接收端套接字地址。在TCP编程中,send函数不需要指定地址,因为目标地址暗含在连接中了。

2.2数据接收函数:recvfrom函数


addr用来存储数据发送端套接字的地址。recvfrom函数在接收数据的同时也获取了发送端套接字地址。而在TCP编程中,是通过accept函数来获取与服务器建立连接的套接字地址。

3、实例(这些代码都是跟着国嵌的视频课程编写的,都是比较简单的功能)
编写一个UDP服务器程序和客户端程序,实现功能是:在客户端通过键盘输入一些字符,这些字符会发送到服务器,并在服务器上打印出来。

服务器端程序:

#include<stdio.h>
#include<sys/socket.h>
#include<string.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<stdlib.h>

#define portnum 123//定义一个端口号
#define MSG_SIZE 128

int main()
{
	int sockfd;
	struct sockaddr_in server_addr;
	struct sockaddr_in client_addr;
	char buffer[MSG_SIZE];
	int addr_len , n ;//地址长度
	//1 创建套接字
	if((sockfd=socket( AF_INET, SOCK_DGRAM, 0)) == -1)//如果创建套接字失败
	{
		printf("create socket error!\n");
			exit(1);	
	}
	
	//2.1 初始化地址
	bzero(&server_addr, sizeof(struct sockaddr_in));
	
	server_addr.sin_family = AF_INET;
	server_addr.sin_port = htons( portnum);//转换成网络字节序
	server_addr.sin_addr.s_addr = htonl(INADDR_ANY );//INADDR_ANY:接收任何消息,转换成网络字节序
	
	//2.2 绑定地址
	bind( sockfd, (struct sockaddr *)&server_addr, sizeof(struct sockaddr) );
	
	//3 接收数据
	while(1)
	{
		addr_len = sizeof(struct sockaddr);
		bzero(buffer, sizeof(buffer));//每次接收前,现将buffer清空
		n = recvfrom(sockfd, buffer, MSG_SIZE, 0,(struct sockaddr *)&client_addr,&addr_len);
		
		//打印出客户机地址
		printf("Receive data from:%s\n", (inet_ntoa(client_addr.sin_addr)) );
		
		buffer[n] = '\0';	
		printf("server receive: %s\n", buffer);
	}
	
	//4 结束连接
	close(sockfd );
	
	return 0 ;
}
客户端程序:(运行程序时,需要指定服务器地址)

#include<stdio.h>
#include<sys/socket.h>
#include<string.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<stdlib.h>

#define BUF_SIZE 128
#define PORT 123//端口必须与服务器一样

int main( int argc, char **argv)
{
	
	int sockfd;
	char buffer[BUF_SIZE];
	struct sockaddr_in server_addr;
	
	if(argc!=2)//如果输入的包含命令名称在内的数据 !=2
	{
		printf("Usage: %s  server_ip\n", argv[0]);
		exit(1);	
	}
	
	//1 创建套接字		
	if((sockfd=socket( AF_INET, SOCK_DGRAM, 0)) == -1)//如果创建套接字失败
	{
		printf("create socket error!\n");
			exit(1);	
	}
	
	//服务器地址初始化
	bzero(&server_addr, sizeof(struct sockaddr_in));
	
	server_addr.sin_family = AF_INET;
	server_addr.sin_port = htons( PORT);//转换成网络字节序
	inet_aton(argv[1],&server_addr.sin_addr);//将键盘输入的字符串格式地址,转化成整型IP
	 
	//2 发送数据
	while(1)
	{
		printf("Please input char:\n");
		fgets( buffer, BUF_SIZE,stdin);
		sendto(sockfd,buffer,strlen(buffer),0,(struct sockaddr *)(&server_addr),sizeof(struct sockaddr));
		bzero(buffer,BUF_SIZE );//每次发送完,将buffer清空
		
	}
	//3关闭连接
	close( sockfd);
}

对比:

TCP协议(传输控制协议)和UDP协议(用户数据报协议)的区别之一是:前者是面向链接的协议,后者是无连接协议。若要使用TCP来传输数据,则传输数据之前,客户端与服务器必须先建立连接。而使用UDP传输数据则不需要建立连接,只需要事先确定数据接收端套接字的地址。相比而言,使用TCP来传输数据要可靠的多。这里有一个简单的比喻来说明TCP和UDP传输数据的差异:

用UDP传输数据相当于给某人邮寄信件。虽然可以邮寄很多信件,但是无法保证信件的投递次序,且在邮递过程中有可能会丢失一些信件。每封信都写有收件人的地址,且没封信可能到达不同的接收者。

用TCP传输数据相当于给某人打电话。首先要通过电话建立一个连接,然后才能彼此双向通信。只有先接通电话才能聊天嘛。建立的每个连接都是端到端的通信通道。会话中不包含地址信息,就像呼叫的两端存在一个点对点的虚拟连接,并且连接本身暗含特定的源和目的地。


参考资料:《UNIX环境高级编程》

前一篇文章:linux网络编程(一)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

转载请注明出处:
作者:Andoubi

2017-04-07 22:28:55 qq_28877125 阅读数 164

UDP信息传输

Linux服务器

/************linux-udp-image-server*****************/
/**
* 这是一个linux 服务器端程序,不停的接收数据并显示出来
*/

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include <errno.h>

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <sys/time.h>

#define SER_PORT 3000  
#define MAX_DATA 51200  //50kb  

#ifndef bool  
#define bool int  
#define true 1  
#define false 0  
#endif



int main(int argc,char* argv[]){

        int serv_sock;/*服务器端socket描述符*/
        int clnt_addr_len;
        int recv_len;

        char message[MAX_DATA];

        struct  sockaddr_in serv_addr,clnt_addr;/*服务器地址与客户端地址*/

        serv_sock = socket(AF_INET, SOCK_DGRAM, 0);
        if(serv_sock < 0)
        {
                printf("UDP socket creation error!\n");
                exit(1);
        }
        else
        {
                printf("UDP socket is creat successful!\n");

        }

        bzero(&serv_addr, sizeof(serv_addr));
        serv_addr.sin_family=AF_INET;
        serv_addr.sin_addr.s_addr=htonl(INADDR_ANY);
        serv_addr.sin_port=htons(SER_PORT);

        if(bind(serv_sock, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) < 0)
        {
                printf("bind() error!\n");
                exit(1);
        }
        else
        {
                printf("bind is success!\n");

        }
        while(1)
        {
                clnt_addr_len=sizeof(clnt_addr);
                recv_len=recvfrom(serv_sock, message, MAX_DATA, 0, (struct sockaddr*)&clnt_addr, &clnt_addr_len);
                printf("%s\n",message);
                sendto(serv_sock, message, recv_len, 0, (struct sockaddr*)&clnt_addr, clnt_addr_len);
        }
        close(serv_sock);
        return 0;
}

windows客户端

/********************windows-client******************/

#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <winsock2.h>

#define SERV_PORT 3000  
#define MAX_DATA 51200  //50kb  
#define FILE_LENGTH 921654 //图片大小

#pragma comment(lib,"ws2_32.lib")

#ifndef bool  
#define bool int  
#define true 1  
#define false 0  
#endif

int main(int argc, char* argv[]) {
    WORD socketVersion = MAKEWORD(2, 2);
    WSADATA wsaData;
    SOCKADDR_IN sin;
    SOCKADDR_IN addr_client;
    SOCKET hSocket;
    int client_len;
    int recv_num;
    int send_num;
    char recv_buf[20];
    char send_path[1024];
    char send_over[9] = "send over";
    char send_buf[MAX_DATA];
    FILE *fd = NULL;

    if (WSAStartup(socketVersion, &wsaData) != 0)
    {
        return 0;
    }


    hSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
    if (hSocket == INVALID_SOCKET)
        printf("socket() error!");

    sin.sin_family = AF_INET;
    sin.sin_port = htons(SERV_PORT);
    sin.sin_addr.S_un.S_addr = inet_addr("101.200.46.138");
    int len = sizeof(sin);

    int nNetTimeout = 2000;//设置超时
    if (SOCKET_ERROR == setsockopt(hSocket, SOL_SOCKET, SO_REUSEADDR, (char *)&nNetTimeout, sizeof(int)))
    {
        printf("Set Ser_RecTIMEO error !\r\n");
        exit(1);
    }

    while (1) {//不停的发
        char * sendData = "from yuanlifu!";
        sendto(hSocket, sendData, strlen(sendData), 0, (SOCKADDR*)&sin, len);

        char recvData[255];
        int ret = recvfrom(hSocket, recvData, 255, 0, (SOCKADDR *)&sin, &len);
        if (ret > 0)
        {
            recvData[ret] = 0x00;
            printf(recvData);
        }
    }

    closesocket(hSocket);
    WSACleanup();
    return 0;
}

——————————————————————————

UDP文件传输

2016-11-06 21:15:24 Insanity666 阅读数 132
用户数据报文协议(UDP):

        UDP 提供不可靠的非连接型传输层服务,它允许在源和目的地之间传送数据,而不必在传送数据之前建立对话。它主要用于那些非连接型的应用程序,如:视频点播


UDP流程图:


服务器代码:

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <string.h>
#include <arpa/inet.h>

#define PORTNUM 3333

int main()
{
    int sock_fd;
    struct sockaddr_in my_addr;
    struct sockaddr_in fromaddr;
    int addrlen = sizeof(struct sockaddr);
    struct sockaddr_in addr_client;
    char buf[1024];
    //1.socket
    sock_fd = socket(AF_INET,SOCK_DGRAM,0);
    if(sock_fd < 0)
    {
        printf("socket error\n");
exit(1);
    }
    //2.bind
    bzero(&my_addr,sizeof(struct sockaddr_in));
    my_addr.sin_family = AF_INET;
    my_addr.sin_port = htons(PORTNUM);
    my_addr.sin_addr.s_addr = INADDR_ANY;
    //my_addr.sin_addr.s_addr = inet_addr("192.168.1.11");
    if(bind(sock_fd,(struct sockaddr *)(&my_addr),addrlen) < 0)
    {
        printf("bind error\n");
close(sock_fd);
exit(1);
    }
    while(1)
    {
        bzero(buf,sizeof(buf));
bzero(&fromaddr,sizeof(fromaddr));
        //3.recv
        if(recvfrom(sock_fd,buf,1024,0,(struct sockaddr *)(&fromaddr),&addrlen) > 0)
        {
            printf("buf = %s\n",buf);
        }
        if(sendto(sock_fd,"ok",1024,0,(struct sockaddr *)(&fromaddr),sizeof(struct sockaddr)) < 0)
        {
            printf("send error\n");
        }
if(strncmp(buf,"quit",4) == 0)
{
   break;
}
    }
    //4.close
    close(sock_fd);

    return 0;
}


客户端:

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <string.h>
#include <arpa/inet.h>

#define PORTNUM 3333

int main()
{
    int sock_fd;
    struct sockaddr_in toaddr;    
    struct sockaddr_in fromaddr;
    char buf[1024];
    int addrlen = sizeof(struct sockaddr);
    //1.socket
    sock_fd = socket(AF_INET,SOCK_DGRAM,0);
    if(sock_fd < 0)
    {
        printf("socket error\n");
exit(1);
    }
    //2.send
    bzero(&toaddr,sizeof(toaddr));
    toaddr.sin_family = AF_INET;
    toaddr.sin_port = htons(PORTNUM);
    toaddr.sin_addr.s_addr = inet_addr("192.168.1.11");
    printf("please input buf:");
    scanf("%s",buf);
    if(sendto(sock_fd,(void *)buf,1024,0,(struct sockaddr *)(&toaddr),sizeof(struct sockaddr)) < 0)
    {
        printf("send error\n");
    }
    bzero(&fromaddr,sizeof(fromaddr));
    if(recvfrom(sock_fd,buf,1024,0,(struct sockaddr *)(&fromaddr),&addrlen) > 0)
    {
        printf("buf = %s\n",buf);
    }
    //3.close
    close(sock_fd);

    return 0;
}



Linux UDP编程

阅读数 1377

linux之UDP网络编程

阅读数 1156

Linux下的UDP编程

阅读数 198

没有更多推荐了,返回首页