网络编程 day03 (linux) UDP 协议的传输 与函数 getsockopt setsockopt sendto(经socket传送数据)recvfrom

1.UDP协议的特点

UDP(User Datagram Protocol)用户数据报协议,是不可靠的无连接的协议。在数据发送前,因为不需要进行连接,所以可以进行高效率的数据传输。

适用情况:

1.发送小尺寸数据(如对DNS服务器进行IP地址查询时)

2.在接收到数据,给出应答较困难的网络中使用UDP。(如:无线网络)

3.适合于广播/组播式通信中。

4.MSN/QQ/Skype等即时通讯软件的点对点文本通讯以及音视频通讯通常采用UDP协议

5.流媒体、VOD、VoIP、IPTV等网络多媒体服务中通常采用UDP方式进行实时数据传输


2.UDP的介绍

UDP是无连接的、不可靠的数据协议报,而TCP是面向连接的,提供可靠的字节流。然而,有些情况下更适合用UDP而不是TCP。有些流行的应用程序是用UDP实现的:DNS(域名系统)、NFS(网络文件系统)和SNMP(简单网络管理协议)就是这样的例子。Tftp协议:udp


3.UDP 的传输


4.UDP和TCP区别

1.UDP协议是一种无连接的协议

2.不需要通过三次握手来建立一个连接

3.一个UDP应用可同时作为应用的客户或服务器方

4.由于UDP协议并不需要建立一个明确的连接,因此建立UDP应用要比建立TCP应用简单得多


5.函数

getsockopt  查看套接字的属性

 原型 :int getsockopt(int sockfd, int level, int optname,void *optval, socklen_t *optlen);

参数:

sockfd     网络 套接字

level       SOL_SOCKET

optname   SO_BROADCAST

optval:指针,指向存放所获得选项值的缓冲区。

optlen:指针,指向optval缓冲区的长度值。

返回值:若无错误发生,getsockopt()返回0。否则的话,返回SOCKET_ERROR错误,应用程序可通过WSAGetLastError()获取相应错误代码。


 

setsockopt 修改套接字的属性

原型:  int setsockopt(int sockfd, int level, int optname, const void *optval, socklen_t optlen);

参数:

sockfd     网络 套接字

level       SOL_SOCKET

optname   SO_BROADCAST

optval:指针,指向存放所获得选项值的缓冲区。

optlen:指针,指向optval缓冲区的长度值。

返回值:若无错误发生,getsockopt()返回0。否则的话,返回SOCKET_ERROR错误,应用程序可通过WSAGetLastError()获取相应错误代码。

sendto  UDP 发送信息

原型: ssize_t sendto(int socket, void *message, size_t length, int flags, struct sockaddr *dest_addr, socklen_t dest_len);

参数:

socket           网络套接字

message      字符串的地址

length           字符串的长度

flags            一般设0

dest_addr    发送地点 的 struct sockaddr 类型的参数 

dest_len     struct sockaddr 类型的参数 的大小。

返回值 成功则返回接收到的字符数,失败则返回-1,错误原因存于errno中。

recvform  UDP 接收信息

原型 :ssize_t recvfrom(int socket, void *buffer, size_t length, int flags, struct sockaddr *address, socklen_t *address_len);

参数:

socket           网络套接字

buffer       字符串的地址

length           字符串的长度

flags            一般设0

address    接受信息地点 的 struct sockaddr 类型的参数 

address_len     struct sockaddr 类型的参数 的大小。

返回值 成功则返回接收到的字符数,失败则返回-1,错误原因存于errno中。


6. 程序的功能:实现UDP 的通信 

要求: 1.服务端 给客户端 发送菜单1. sendtime  2.savetime

                客户端 回复sendtime   服务端就给客户端发送  时间。

                 客户端 回复savetime   服务端就给文件里面存放  时间。

服务器   (客户端  telnet 命令   )(多用户也可以 )

代码:

/************************************************************************************************************************************************************************************************************************
 *文件名:
 *作  者:She001
 *时  间:
 *版  本:
 *作  用: 线程的多用户连接菜单的输入
****************************************************************************************************************************************************************************************************************************/
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<stdlib.h>
#include<stdbool.h>
#include<time.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<errno.h>
#include<sys/wait.h>
#include<a.out.h>
#include<signal.h>
#include<stdarg.h>
#include<sys/socket.h>
#include<utime.h>
#include<sys/utsname.h>
#include<sys/times.h>
#include<sys/un.h>
#include<ctype.h>
#include<dirent.h>
#include<sys/time.h>
#include<sys/resource.h>
#include<syslog.h>
#include<pthread.h>
#include<semaphore.h>
#include<sys/time.h>
#include<sys/ipc.h>
#include<sys/sem.h>
#include<sys/msg.h>
#include<arpa/inet.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<netdb.h>


void time1()
{
	FILE* fp =fopen("1.txt","a+");
	time_t tm1 =time(NULL); //输出函
	char *s = ctime(&tm1);
	fprintf(fp,"%s\n",s);
	fclose(fp);
	
}
char * return_time()
{
	//FILE* fp =fopen("1.txt","a+");
	time_t tm1 =time(NULL); //输出函
	char *s = ctime(&tm1);
	//fprintf(fp,"%s\n",s);
	//fclose(fp);
	return s;
}



void *pthread_fun(void* arg)
{
	int cid =*((int *)arg);
	char buff[128]="";
	int len =0;
	char sendbuff[128]="";
	char caidan[1000]=" 1. sendtime  2.savetime\n";
	while(1)
	{
		bzero(buff,sizeof(buff));
		send(cid,caidan,strlen(caidan),0);
		recv(cid,buff,sizeof(buff),0);
		printf("cid =%d  :   %s",cid,buff);
		if(strncmp(buff,"quit",4)==0)
		{
			shutdown(cid,SHUT_RDWR);
			close(cid);
			break;
		}
		if(strncmp(buff,"sendtime",8)==0)
		{
			printf("1\n");
			bzero(buff,sizeof(buff));
			strcpy(buff,return_time());
			printf("%s\n",buff);
			send(cid,buff,strlen(buff),0);

		}
		if(strncmp(buff,"savetime",8)==0)
		{
			time1();
		}
		
	}
	return NULL;
}

int main(int argc,char *argv[])
{
	//参数判断
		if(argc <3)
		{
			perror("agc error\n");
			return -1;
		}

		//1.创建套接字
		int sid =socket(AF_INET,SOCK_STREAM,0);//服务端的sid
		if(sid<0)
		{
			perror("socket error\n");
			return -2;
		}
		printf("sid=%d\n",sid);
		

		//2.绑定 bind  函数经常失败
		struct sockaddr_in server_addr={0};
		server_addr.sin_family=AF_INET;
		server_addr.sin_port=htons(atoi(argv[2])); //端口号的转换  字符串-主机整数--网络整数
		server_addr.sin_addr.s_addr=inet_addr(argv[1]);//主机字符串 --网络字节序
		int reslg=bind(sid,(struct sockaddr*)&server_addr,sizeof(server_addr));
		if(reslg==-1)
		{
			perror("bind error\n");
			return -2;
		}
		printf("bind  success   ok\n");
		

		//3.监听 listen 
		if(listen(sid,10)<0)
		{
			perror("listen error\n");
			return -3;
		}
		printf("listen is successful\n");



		//4.accept()
		//建立连接
		//struct sockaddr_in client_addr ={0};
		//int size =sizeof(client_addr);
		int cid=-1;
		char buff[1024]="";
		char kk[100]="";
		pthread_t tid=0;
		while(1)
		{	
			cid=accept(sid,NULL,NULL);
			printf("cid =%d\n",cid);
			if(cid!=-1)
			{
				//客户连接成功!
				pthread_create(&tid,NULL,pthread_fun,&cid);
			}
		}
		


       return 0;

}

7. 写一个可以连接上面的客户端

代码:

/************************************************************************************************************************************************************************************************************************
 *文件名:
 *作  者:She001
 *时  间:
 *版  本:
 *作  用:客户端
****************************************************************************************************************************************************************************************************************************/
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<stdlib.h>
#include<stdbool.h>
#include<time.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<errno.h>
#include<sys/wait.h>
#include<a.out.h>
#include<signal.h>
#include<stdarg.h>
#include<sys/socket.h>
#include<utime.h>
#include<sys/utsname.h>
#include<sys/times.h>
#include<sys/un.h>
#include<ctype.h>
#include<dirent.h>
#include<sys/time.h>
#include<sys/resource.h>
#include<syslog.h>
#include<pthread.h>
#include<semaphore.h>
#include<sys/time.h>
#include<sys/ipc.h>
#include<sys/sem.h>
#include<sys/msg.h>
#include<arpa/inet.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<netdb.h>
//
int main(int argc,char *argv[])
{

		int sid =socket(AF_INET,SOCK_STREAM,0);//服务端的sid
		if(sid<0)
		{
			perror("socket error\n");
			return -2;
		}
		printf("sid=%d\n",sid);
		

		//2.绑定 bind  函数经常失败
		struct sockaddr_in server_addr={0};
		server_addr.sin_family=AF_INET;
		server_addr.sin_port=htons(atoi(argv[2])); //端口号的转换  字符串-主机整数--网络整数
		server_addr.sin_addr.s_addr=inet_addr(argv[1]);//主机字符串 --网络字节序
		while(connect(sid,(struct sockaddr*)&server_addr,sizeof(struct sockaddr)));
		{
			perror("connect  error\n");
			sleep(1);
		}
		printf("connect ok\n");
		char buff[128]="";
		char *str ="hello\r\n";
		while(1)
		{
			bzero(buff,sizeof(buff));
			send(sid,str,strlen(str),0);
			fgets(buff,sizeof(buff),stdin);
			send(sid,buff,strlen(buff),0);
			printf("%s",buff);
		}
	

       return 0;

}


8.修改网络套接字的属性 使他把recvfrom 的堵塞属性 删除

代码:

/************************************************************************************************************************************************************************************************************************
 *文件名:
 *作  者:She001
 *时  间:
 *版  本:
 *作  用:UDP 接受端
****************************************************************************************************************************************************************************************************************************/
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<stdlib.h>
#include<stdbool.h>
#include<time.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<errno.h>
#include<sys/wait.h>
#include<a.out.h>
#include<signal.h>
#include<stdarg.h>
#include<sys/socket.h>
#include<utime.h>
#include<sys/utsname.h>
#include<sys/times.h>
#include<sys/un.h>
#include<ctype.h>
#include<dirent.h>
#include<sys/time.h>
#include<sys/resource.h>
#include<syslog.h>
#include<pthread.h>
#include<semaphore.h>
#include<sys/time.h>
#include<sys/ipc.h>
#include<sys/sem.h>
#include<sys/msg.h>
#include<arpa/inet.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<netdb.h>
//1.UDP 协议 接受端的编程
//1.socket 数据报套接字
//2.bind : 把自己的ip port  绑定好 
//3.recvfrom  读写操作 while(1)  printf() 
//4.close
//





int main(int argc,char *argv[])
{
	if(argc <3)
	{
		perror("argc error\n");
		return -1;
	}
	int cid = socket(AF_INET,SOCK_DGRAM,0);
	if(cid ==-1)
	{
		perror("cid error\n");
		return -2;
	}
	printf("socket ok\n");
	struct sockaddr_in caddr={0};
	caddr.sin_family =AF_INET;
	caddr.sin_port =htons(atoi(argv[2]));
	caddr.sin_addr.s_addr =inet_addr(argv[1]);
	if(bind(cid,(struct sockaddr*)&caddr,sizeof(caddr))<0)
	{
		perror("bind error\n");
		return -2;
	}
	printf("bind success\n");
	//读写操作 read recv readform 堵塞属性
	//一次读 + while(); 循环读      
///
//修改文件描述符号的属性(堵塞属性)
int flg = fcntl(cid,F_GETFL);
int newflg = flg| O_NONBLOCK;
int res = fcntl(cid,F_SETFL,newflg);//转换为不堵塞
		



//不要堵塞的,改回来
//fcntl(cid,F_SETFL,flg);
///
	char buff[128]="";
	struct sockaddr_in saddr={0};
	int size =sizeof(saddr);
	char ip[128]="";
	while(1)
	{
		recvfrom(cid,buff,sizeof(buff)-1,0,(struct sockaddr*)&saddr,&size);
		printf("%d  %s\n",ntohs(saddr.sin_port),inet_ntop(AF_INET,&saddr.sin_addr.s_addr,ip,20));
		printf("%s\n",buff);
		//bzero(buff,sizeof(buff));
		//fgets(buff,sizeof(buff),stdin);
		//sendto(cid,buff,strlen(buff),0,(struct sockaddr*)&caddr,sizeof(struct sockaddr));
		sleep(1);
	
	}
	close(cid);


       return 0;

}

9.程序功能:UDP协议通信    实现你一句,我一句的对话的客户端 (先说话)

代码:

/************************************************************************************************************************************************************************************************************************
 *文件名:
 *作  者:She001
 *时  间:
 *版  本:
 *作  用:UDP 接受端
****************************************************************************************************************************************************************************************************************************/
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<stdlib.h>
#include<stdbool.h>
#include<time.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<errno.h>
#include<sys/wait.h>
#include<a.out.h>
#include<signal.h>
#include<stdarg.h>
#include<sys/socket.h>
#include<utime.h>
#include<sys/utsname.h>
#include<sys/times.h>
#include<sys/un.h>
#include<ctype.h>
#include<dirent.h>
#include<sys/time.h>
#include<sys/resource.h>
#include<syslog.h>
#include<pthread.h>
#include<semaphore.h>
#include<sys/time.h>
#include<sys/ipc.h>
#include<sys/sem.h>
#include<sys/msg.h>
#include<arpa/inet.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<netdb.h>
//1.UDP 协议 接受端的编程
//1.socket 数据报套接字
//2.bind : 把自己的ip port  绑定好 
//3.recvfrom  读写操作 while(1)  printf() 
//4.close
//





int main(int argc,char *argv[])
{
	if(argc <3)
	{
		perror("argc error\n");
		return -1;
	}
	int cid = socket(AF_INET,SOCK_DGRAM,0);
	if(cid ==-1)
	{
		perror("cid error\n");
		return -2;
	}
	printf("socket ok\n");
	struct sockaddr_in caddr={0};
	caddr.sin_family =AF_INET;
	caddr.sin_port =htons(atoi(argv[2]));
	caddr.sin_addr.s_addr =inet_addr(argv[1]);
/*
	if(bind(cid,(struct sockaddr*)&caddr,sizeof(caddr))<0)
	{
		perror("bind error\n");
		return -2;
	}
	printf("bind success\n");
*/
	//读写操作 read recv readform 堵塞属性
	//一次读 + while(); 循环读      
///
//修改文件描述符号的属性(堵塞属性)
//int flg = fcntl(cid,F_GETFL);
//int newflg = flg| O_NONBLOCK;
//int res = fcntl(cid,F_SETFL,newflg);//转换为不堵塞
		



//不要堵塞的,改回来
//fcntl(cid,F_SETFL,flg);
///
	char buff[128]="";
	struct sockaddr_in saddr={0};
	int size =sizeof(saddr);
	char ip[128]="";
	pid_t pid=fork();
	while(1)
	{
			bzero(buff,sizeof(buff));
			fgets(buff,sizeof(buff),stdin);
			sendto(cid,buff,strlen(buff),0,(struct sockaddr*)&caddr,sizeof(struct sockaddr));
			
			
			bzero(buff,sizeof(buff));
			recvfrom(cid,buff,sizeof(buff)-1,0,(struct sockaddr*)&saddr,&size);
			printf("%d  %s\n",ntohs(saddr.sin_port),inet_ntop(AF_INET,&saddr.sin_addr.s_addr,ip,20));
			printf("%s\n",buff);

	
	}
	close(cid);


       return 0;

}

10.UDP协议通信    实现你一句,我一句的对话的服务端 (先接受信息,再发送)

代码:

/************************************************************************************************************************************************************************************************************************
 *文件名:
 *作  者:She001
 *时  间:
 *版  本:
 *作  用:UDP 接受端
****************************************************************************************************************************************************************************************************************************/
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<stdlib.h>
#include<stdbool.h>
#include<time.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<errno.h>
#include<sys/wait.h>
#include<a.out.h>
#include<signal.h>
#include<stdarg.h>
#include<sys/socket.h>
#include<utime.h>
#include<sys/utsname.h>
#include<sys/times.h>
#include<sys/un.h>
#include<ctype.h>
#include<dirent.h>
#include<sys/time.h>
#include<sys/resource.h>
#include<syslog.h>
#include<pthread.h>
#include<semaphore.h>
#include<sys/time.h>
#include<sys/ipc.h>
#include<sys/sem.h>
#include<sys/msg.h>
#include<arpa/inet.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<netdb.h>
//1.UDP 协议 接受端的编程
//1.socket 数据报套接字
//2.bind : 把自己的ip port  绑定好 
//3.recvfrom  读写操作 while(1)  printf() 
//4.close
//





int main(int argc,char *argv[])
{
	if(argc <3)
	{
		perror("argc error\n");
		return -1;
	}
	int cid = socket(AF_INET,SOCK_DGRAM,0);
	if(cid ==-1)
	{
		perror("cid error\n");
		return -2;
	}
	printf("socket ok\n");
	struct sockaddr_in caddr={0};
	caddr.sin_family =AF_INET;
	caddr.sin_port =htons(atoi(argv[2]));
	caddr.sin_addr.s_addr =inet_addr(argv[1]);
	if(bind(cid,(struct sockaddr*)&caddr,sizeof(caddr))<0)
	{
		perror("bind error\n");
		return -2;
	}
	printf("bind success\n");
	//读写操作 read recv readform 堵塞属性
	//一次读 + while(); 循环读      
///
//修改文件描述符号的属性(堵塞属性)
//int flg = fcntl(cid,F_GETFL);
//int newflg = flg| O_NONBLOCK;
//int res = fcntl(cid,F_SETFL,newflg);//转换为不堵塞
		



//不要堵塞的,改回来
//fcntl(cid,F_SETFL,flg);
///
	char buff[128]="";
	struct sockaddr_in saddr={0};
	int size =sizeof(saddr);
	char ip[128]="";
	pid_t pid=fork();
	while(1)
	{
			bzero(buff,sizeof(buff));
			recvfrom(cid,buff,sizeof(buff)-1,0,(struct sockaddr*)&saddr,&size);
			printf("%d  %s\n",ntohs(saddr.sin_port),inet_ntop(AF_INET,&saddr.sin_addr.s_addr,ip,20));
			printf("%s\n",buff);
	
			bzero(buff,sizeof(buff));
			fgets(buff,sizeof(buff),stdin);
			sendto(cid,buff,strlen(buff),0,(struct sockaddr*)&saddr,sizeof(struct sockaddr));
		
	
	}
	close(cid);


       return 0;

}

11.程序的功能 :实现 每个用户的无限说话,和无限接受信息 (利用了 进程  )(有四个参数  ,首先是   自己的 IP   自己的端口号 port    别人的ip   别人的port  )

再次说 一下 sendto   recvform  这两个函数 

sendto 函数 这里面的  sockaddr_in  类型的参数  是 要发送给那个人的    参数(发给谁,就填谁的信息)

recvfrom 函数 这里的   sockaddr_in  类型的参数  只要是这样类型的参数就行 ,但是当recvfrom 运行成功之后 ,这个参数会储存   那个发你信息的人     的身份(IP  和  port)。

代码:

/************************************************************************************************************************************************************************************************************************
 *文件名:
 *作  者:She001
 *时  间:
 *版  本:
 *作  用:UDP 接受端
****************************************************************************************************************************************************************************************************************************/
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<stdlib.h>
#include<stdbool.h>
#include<time.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<errno.h>
#include<sys/wait.h>
#include<a.out.h>
#include<signal.h>
#include<stdarg.h>
#include<sys/socket.h>
#include<utime.h>
#include<sys/utsname.h>
#include<sys/times.h>
#include<sys/un.h>
#include<ctype.h>
#include<dirent.h>
#include<sys/time.h>
#include<sys/resource.h>
#include<syslog.h>
#include<pthread.h>
#include<semaphore.h>
#include<sys/time.h>
#include<sys/ipc.h>
#include<sys/sem.h>
#include<sys/msg.h>
#include<arpa/inet.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<netdb.h>
//1.UDP 协议 接受端的编程
//1.socket 数据报套接字
//2.bind : 把自己的ip port  绑定好 
//3.recvfrom  读写操作 while(1)  printf() 
//4.close
//





int main(int argc,char *argv[])
{
	if(argc <5)
	{
		perror("argc error\n");
		return -1;
	}
	int cid = socket(AF_INET,SOCK_DGRAM,0);
	if(cid ==-1)
	{
		perror("cid error\n");
		return -2;
	}
	printf("socket ok\n");
	struct sockaddr_in caddr={0};
	caddr.sin_family =AF_INET;
	caddr.sin_port =htons(atoi(argv[2]));
	caddr.sin_addr.s_addr =inet_addr(argv[1]);

	if(bind(cid,(struct sockaddr*)&caddr,sizeof(caddr))<0)
	{
		perror("bind error\n");
		return -2;
	}
	printf("bind success\n");
	char buff[128]="";
	struct sockaddr_in saddr={0};
	saddr.sin_family =AF_INET;
	saddr.sin_port =htons(atoi(argv[4]));
	saddr.sin_addr.s_addr =inet_addr(argv[3]);
	int size =sizeof(saddr);
	char ip[128]="";
	int hh=1;

	
			if(hh==1)
			{
				hh=0;
				pid_t pid=fork();
				if(pid==0)
				{
					while(1)
					{
						bzero(buff,sizeof(buff));
						recvfrom(cid,buff,sizeof(buff)-1,0,(struct sockaddr*)&caddr,&size);
						printf("%d  %s\n",ntohs(saddr.sin_port),inet_ntop(AF_INET,&saddr.sin_addr.s_addr,ip,20));
						printf("%s\n",buff);
					}
				}
				if(pid>0)
				{
					while(1)
					{
						bzero(buff,sizeof(buff));
						fgets(buff,sizeof(buff),stdin);
						sendto(cid,buff,strlen(buff),0,(struct sockaddr*)&saddr,sizeof(struct sockaddr));			
					}
				}
			}
			close(cid);

       return 0;

}


12.程序内容:查看和设置套接字的各种选项

getsockopt

setsockopt

代码:

/************************************************************************************************************************************************************************************************************************
 *文件名:
 *作  者:She001
 *时  间:
 *版  本:
 *作  用:获取 socket 的属性 或者是修改  单播 1对1  组播:对UDP 用户组发送数据
****************************************************************************************************************************************************************************************************************************/
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<stdlib.h>
#include<stdbool.h>
#include<time.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<errno.h>
#include<sys/wait.h>
#include<a.out.h>
#include<signal.h>
#include<stdarg.h>
#include<sys/socket.h>
#include<utime.h>
#include<sys/utsname.h>
#include<sys/times.h>
#include<sys/un.h>
#include<ctype.h>
#include<dirent.h>
#include<sys/time.h>
#include<sys/resource.h>
#include<syslog.h>
#include<pthread.h>
#include<semaphore.h>
#include<sys/time.h>
#include<sys/ipc.h>
#include<sys/sem.h>
#include<sys/msg.h>
#include<arpa/inet.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<netdb.h>
//1.getsockopt  setsockopt
int main(int argc,char *argv[])
{
	int sid =socket(AF_INET,SOCK_DGRAM,0);
	printf("sid =%d \n",sid);
	//获取属性 0没有  1有
	int value;
	int size =sizeof(value);
	getsockopt(sid,SOL_SOCKET,SO_BROADCAST,&value,&size);
	if(!value)
	{
		printf("it  has no brodcast function\n");
		printf("%d\n",value);
	}
	else
	{
		printf("it has brodcasr function\n");
		printf("%d\n",value);
	}
	
	//设置属性 0没有 1有
	value =1;
	int gg=setsockopt(sid,SOL_SOCKET,SO_BROADCAST,&value,sizeof((value)));
	if(gg<0)
	{
		printf("setsockopt error\n");
	}
	printf("setsockopt ok\n");

	//在设置之后 ,再次查看
	getsockopt(sid,SOL_SOCKET,SO_BROADCAST,&value,&size);
	if(!value)
	{
		printf("it  has no brodcast function\n");
		printf("%d\n",value);
	}
	else
	{
		printf("it has brodcasr function\n");
		printf("%d\n",value);
	}



       return 0;

}

13.程序功能:广播  接受端

代码:

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

//广播接收方编程:
//1.创建数据报套接字
//2.修改套接字属性为可以广播 接收方要绑定,发送方不用绑定
//3.接收方的ip地址选用INADDR_ANY 
	//运行的过程中,把端口号写成不同的。
//4.接收数据
//5.结束

//应用程序 端口号
int main(int argc,char**argv)
{	
	//1.参数判断
	if(argc < 2)
	{
		perror("argc error\n");
		return -1;
	}

	//2.建立数据报套接字
	int cid = socket(AF_INET,SOCK_DGRAM,0);
	if(cid < 0)
	{
		perror("socket error\n");
		return -1;
	}
	printf("socket dgram success:%d\n",cid);
	
	//3.修改数据报套接字的属性,允许广播
	int value = 0 ;
	int size = sizeof(value);
	if(getsockopt(cid,SOL_SOCKET,SO_BROADCAST,&value,&size))
	{
		perror("getsockopt error\n");
		return -1;
	}
	printf("getsockopt is ok\n");

	//把结果显示出来
	printf("before value is %d\n",value);	
	value = 1;
	if(setsockopt(cid,SOL_SOCKET,SO_BROADCAST,&value,size))
	{
		perror("setsockopt is error\n");
		return -2;
	}
	printf("setsockopt is ok\n");
	//再获取udp属性,查看一下
	if(getsockopt(cid,SOL_SOCKET,SO_BROADCAST,&value,&size))
	{
		perror("getsockopt error\n");
		return -1;
	}
	printf("after value is %d\n",value);

	struct sockaddr_in saddr = {0},baddr = {0};

	//3.绑定:绑定是绑定当前cid和当前id和地址,本地
	saddr.sin_family = AF_INET;
	//核心转储通常是因为 少参数造成的。
	saddr.sin_port = htons(10000);
	saddr.sin_addr.s_addr = INADDR_ANY;

	if(bind(cid,(struct sockaddr*)&saddr,sizeof(saddr)))
	{
		perror("bind error\n");
		return -1;
	}
	printf("bind is ok\n");

	char ip[18] = "";
	//4.接收发送端传来的数据
	char buff[128] = "";
	int size1 = sizeof(baddr);
	int len = recvfrom(cid,buff,sizeof(buff)-1,0,(struct sockaddr*)&baddr,&size1);
	//网络字节序转换成主机字节序端口号
	printf("server port:%d\n",ntohs(saddr.sin_port));
	printf("recv len = %d\n",len);
	//网络字节序转换成主机字节序字符串
	printf("server addr : %s\n",inet_ntop(AF_INET,&baddr.sin_addr.s_addr,ip,sizeof(ip)));
	//接收到的内容
	printf("content is : %s\n",buff);

	//4.关闭套接字
	close(cid);

}



14.程序功能:广播发送端

代码:

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

//1.udp广播发送端编程
//1.建立数据报套接字
//2.修改数据报套接字属性
//3.发送端虽然不绑定,但是要编写要发送给谁的ip,所以,ip地址也要填写INADDR_BROADCAST
//4.发送
//5.结束

//要联网1对多,应用程序 端口号
int main(int argc,char**argv)
{	
	//1.参数判断
	if(argc < 2)
	{
		perror("argc error\n");
		return -1;
	}
	//2.建立数据报套接字
	int sid = socket(AF_INET,SOCK_DGRAM,0);
	if(sid < 0)
	{
		perror("socket error\n");
		return -1;
	}
	printf("socket dgram success:%d\n",sid);
	
	//3.修改套接字属性
	int value = 0 ;
	int size = sizeof(value);
	if(getsockopt(sid,SOL_SOCKET,SO_BROADCAST,&value,&size))
	{
		perror("getsockopt error\n");
		return -1;
	}
	printf("getsockopt is ok\n");

	//把结果显示出来
	printf("before value is %d\n",value);	
	value = 1;
	if(setsockopt(sid,SOL_SOCKET,SO_BROADCAST,&value,size))
	{
		perror("setsockopt is error\n");
		return -2;
	}
	printf("setsockopt is ok\n");
	//再获取udp属性,查看一下
	if(getsockopt(sid,SOL_SOCKET,SO_BROADCAST,&value,&size))
	{
		perror("getsockopt error\n");
		return -1;
	}
	printf("after value is %d\n",value);

	struct sockaddr_in raddr = {0};
	raddr.sin_family = AF_INET;
	raddr.sin_port = ntohs(atoi(argv[1]));
	raddr.sin_addr.s_addr = INADDR_BROADCAST;
	
	//发送给第一个接受端
	char *buff = "hello linux";
	int len = sendto(sid,buff,strlen(buff),0,(struct sockaddr*)&raddr,sizeof(raddr));
	printf("send len = %d\n",len);

	//4.关闭套接字
	close(sid);

}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值