栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Linux网络编程(2)

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Linux网络编程(2)

tcp点播

  1. 制定通信规则:程序员自己制定的
    客户端发给服务器的信息,服务器都能收到,但是服务器无法判断收到的信息究竟是要广播给所有人,还是要点播给某个人
    比如:制定了如下规则(仅供参考)
    all:hello --》表示广播
    ip地址:端口号:hello --》表示点播给ip对应的客户端
    通信规则总体的原则:让服务器能够清楚地知道该如何处理信息
    2. 刻意练习
    有目的强迫自己使用讲过的知识点

udp协议
1. 通信的流程
udp谁先发送谁就是发送端
发送端 接收端
socket(SOCK_DGRAM) socket(SOCK_DGRAM)
bind() bind()
收发信息 收发信息
close() close()
2. 相关的接口函数
(1)发送信息
ssize_t sendto(int socket, const void *message, size_t length,int flags, const struct sockaddr *dest_addr, socklen_t dest_len);
返回值:发送的字节数 失败 -1
参数:前面四个参数跟send一样
dest_addr --》对方的ip和端口号
(2)接收信息
ssize_t recvfrom(int socket, void *restrict buffer, size_t length, int flags, struct sockaddr *restrict address, socklen_t *restrict address_len);
返回值(重点):
区别recv/read的返回值
recvfrom 成功返回接收的字节数
失败 -1
对方退出了,recvfrom依然阻塞,也不会返回0
参数:前面四个参数跟recv一样
address --》存储对方的ip和端口号(谁发信息给我,就存放谁的ip和端口号)
address_len --》地址长度,要求是指针
3. udp广播
发送端 接收端
socket() socket()
bind() bind()
//设置套接字的属性为可以广播 recvfrom()
setsockopt() close()
sendto()(重点:必须使用广播地址)
close()
(1)设置套接字的属性为可以广播
int on=1;
setsockopt(udpsock,SOL_SOCKET,SO_BROADCAST,&on,sizeof(on));
4. udp组播
组播:是广播的一种特殊形式,给指定组里面的所有主机发送信息
发送端 接收端
socket() socket()
bind() bind()
//设置套接字的属性为可以广播 //把接收端添加到组播组里面(重点)
setsockopt() recvfrom()
sendto()(重点:必须使用组播地址) close()
close()
(1)把接收端添加到组播组里面(重点)
struct ip_mreq mreq; //定义结构体变量存放组播地址
bzero(&mreq, sizeof(mreq));
mreq.imr_multiaddr.s_addr = inet_addr(“跟发送端使用的组播地址一致”); // D类地址
mreq.imr_interface.s_addr = htonl(INADDR_ANY); // 必须用这个宏定义
setsockopt(sockfd, IPPROTO_IP, IP_ADD_MEMBERSHIP,&mreq, sizeof(mreq));

ip地址分类
分为: A B C D四类地址
10.45.56,100 —》A类地址
TCP广播
服务器

#include "myhead.h"


//定义内核链表
struct clientlist
{
	char ip[16]; //存放ip
	unsigned short someport; //存放端口号
	int sock; //存放套接字
	struct list_head mypoint;
};

struct clientlist *myhead;
//初始化链表头
struct clientlist *init_list()
{
	struct clientlist *head=malloc(sizeof(struct clientlist));
	INIT_LIST_HEAD(&(head->mypoint));
	return head;
}
void *routine(void *arg)
{
	int ret;
	char buf[100];
	struct clientlist *p=(struct clientlist *)arg;
	struct clientlist *pos,*n;
	while(1)
	{
		bzero(buf,100);
		ret=read(p->sock,buf,100); //接收某个客户端发送的信息
		if(ret==0) //说明客户端退出
		{
			//删除断开的客户端
			list_for_each_entry_safe(pos, n,&(myhead->mypoint),mypoint)
			{
				if(pos->sock==p->sock)
					list_del(&(pos->mypoint));
			}
			break;
		}
		printf("客户端发送过来的信息是:%sn",buf);
		
		//遍历链表转发出去
		list_for_each_entry(pos,&(myhead->mypoint),mypoint)
		{
			//排除自己
			if(pos->sock!=p->sock)
				write(pos->sock,buf,strlen(buf));
		}
	}
	pthread_exit(NULL);
}
int main()
{
	pthread_t id;
	int tcpsock;
	int newsock;
	int ret;
	char buf[100];
	
	//初始化表头
	myhead=init_list(); 
	
	//定义ipv4地址结构体变量
	struct sockaddr_in bindaddr;
	bzero(&bindaddr,sizeof(bindaddr));
	bindaddr.sin_family=AF_INET;
	bindaddr.sin_addr.s_addr=htonl(INADDR_ANY);  //绑定服务器自己的ip地址
	bindaddr.sin_port=htons(10086); //绑定服务器自己的端口号

	struct sockaddr_in clientaddr;
	bzero(&clientaddr,sizeof(clientaddr));
	int addrsize=sizeof(clientaddr);
	
	
	//创建tcp套接字
	tcpsock=socket(AF_INET,SOCK_STREAM,0);
	if(tcpsock==-1)
	{
		perror("创建tcp套接字!n");
		return -1;
	}
	printf("旧的文件描述符:%dn",tcpsock);
	//绑定ip和端口号
	ret=bind(tcpsock,(struct sockaddr *)&bindaddr,sizeof(bindaddr));
	if(ret==-1)
	{
		perror("绑定失败!n");
		return -1;
	}
	//监听
	ret=listen(tcpsock,8);
	if(ret==-1)
	{
		perror("监听失败!n");
		return -1;
	}
	while(1)
	{
		//接收客户端的连接请求
		newsock=accept(tcpsock,(struct sockaddr *)&clientaddr,&addrsize);
		if(newsock==-1)
		{
			perror("接收客户端的连接请求失败!n");
			return -1;
		}
		printf("有新的客户端连接成功了,新的文件描述符:%dn",newsock);
		printf("有新的客户端连接成功了,他的IP地址是:%sn",inet_ntoa(clientaddr.sin_addr));
		printf("有新的客户端连接成功了,他的端口号是:%hun",ntohs(clientaddr.sin_port));
		//把文件描述符存放到链表中
		struct clientlist *newnode=malloc(sizeof(struct clientlist));
		newnode->sock=newsock;
		strcpy(newnode->ip,inet_ntoa(clientaddr.sin_addr));
		newnode->someport=ntohs(clientaddr.sin_port);
		INIT_LIST_HEAD(&(newnode->mypoint));
		//插入到链表的尾部
		list_add_tail(&(newnode->mypoint),&(myhead->mypoint));
		
		//立马新建线程接收这个客户端发送的信息
		pthread_create(&id,NULL,routine,newnode);
	}
	
}

客户端

#include "myhead.h"


int tcpsock;
void *routine(void *arg)
{
	char buf[100];
	int ret;
	while(1)
	{
		bzero(buf,100);
		ret=read(tcpsock,buf,100);
		if(ret==0) //说明服务器断开连接
		{
			printf("服务器挂了!n");
			exit(-1); //结束整个进程
		}
		printf("服务器转发过来的信息是:%sn",buf);
	}
}
int main()
{
	pthread_t id;
	int ret;
	char buf[100];
	//定义ipv4地址结构体变量
	struct sockaddr_in bindaddr;
	bzero(&bindaddr,sizeof(bindaddr));
	bindaddr.sin_family=AF_INET;
	bindaddr.sin_addr.s_addr=htonl(INADDR_ANY);  //绑定客户端自己的ip地址
	bindaddr.sin_port=htons(10000); //绑定客户端自己的端口号
	
	//定义结构体变量存放对方(服务器)的ip和端口号
	struct sockaddr_in serveraddr;
	bzero(&serveraddr,sizeof(serveraddr));
	serveraddr.sin_family=AF_INET;
	serveraddr.sin_addr.s_addr=inet_addr("192.168.24.3");  //服务器的ip地址
	serveraddr.sin_port=htons(10086); //服务器的端口号
	//创建tcp套接字
	tcpsock=socket(AF_INET,SOCK_STREAM,0);
	if(tcpsock==-1)
	{
		perror("创建tcp套接字!n");
		return -1;
	}
	//绑定ip和端口号
	ret=bind(tcpsock,(struct sockaddr *)&bindaddr,sizeof(bindaddr));
	if(ret==-1)
	{
		perror("绑定失败!n");
		return -1;
	}
	
	//连接服务器
	ret=connect(tcpsock,(struct sockaddr *)&serveraddr,sizeof(serveraddr));
	if(ret==-1)
	{
		perror("连接服务器!n");
		return -1;
	}
	//创建线程专门接收服务器的信息
	pthread_create(&id,NULL,routine,NULL);
	//发送信息给服务器
	while(1)
	{
		bzero(buf,100);
		printf("请输入要发送给服务器的信息!n");
		scanf("%s",buf);
		write(tcpsock,buf,strlen(buf));
	}
	close(tcpsock);
	return 0;
}

TCP广播和点播融合

#include "myhead.h"


pthread_attr_t myattr;
void *fun(void *arg)
{
	pthread_attr_destroy(&myattr);
}
//定义内核链表
struct clientlist
{
	char ip[16]; //存放ip
	unsigned short someport; //存放端口号
	int sock; //存放套接字
	struct list_head mypoint;
};

struct clientlist *myhead;
//初始化链表头
struct clientlist *init_list()
{
	struct clientlist *head=malloc(sizeof(struct clientlist));
	INIT_LIST_HEAD(&(head->mypoint));
	return head;
}
void *routine(void *arg)
{
	int ret;
	char msg[100];
	char buf[100];
	struct clientlist *p=(struct clientlist *)arg;
	struct clientlist *pos,*n;
	while(1)
	{
		bzero(buf,100);
		bzero(msg,100);
		ret=read(p->sock,buf,100); //接收某个客户端发送的信息
		if(ret==0) //说明客户端退出
		{
			//删除断开的客户端
			list_for_each_entry_safe(pos, n,&(myhead->mypoint),mypoint)
			{
				if(pos->sock==p->sock)
					list_del(&(pos->mypoint));
			}
			break;
		}
		printf("客户端%s,端口号:%hu  发送过来的信息是:%sn",p->ip,p->someport,buf);
		//切割字符串,判断究竟是群发还是点播
		char *q=strtok(buf,":");  //all:hello或者20000:hello
		strcpy(msg,strtok(NULL,":"));
		if(strcmp(q,"all")==0) //群发
		{
			//遍历链表转发出去
			list_for_each_entry(pos,&(myhead->mypoint),mypoint)
			{
				//排除自己
				if(pos->sock!=p->sock)
					write(pos->sock,msg,strlen(msg));
			}
		}
		else //点播
		{
			//遍历链表找到要点播的对象
			list_for_each_entry(pos,&(myhead->mypoint),mypoint)
			{
				if(pos->someport==atoi(q))
					write(pos->sock,msg,strlen(msg));
			}
		}
		
		
	}
	pthread_exit(NULL);
}
int main()
{
	signal(SIGINT,fun);
	pthread_t id;
	int tcpsock;
	int newsock;
	int ret;
	char buf[100];
	
	//初始化表头
	myhead=init_list(); 
	
	//定义线程属性变量并初始化
	pthread_attr_init(&myattr);
	
	//调用你想设置的属性对应的接口函数
	pthread_attr_setdetachstate(&myattr,PTHREAD_CREATE_DETACHED);
	
	//定义ipv4地址结构体变量
	struct sockaddr_in bindaddr;
	bzero(&bindaddr,sizeof(bindaddr));
	bindaddr.sin_family=AF_INET;
	bindaddr.sin_addr.s_addr=htonl(INADDR_ANY);  //绑定服务器自己的ip地址
	bindaddr.sin_port=htons(10086); //绑定服务器自己的端口号

	struct sockaddr_in clientaddr;
	bzero(&clientaddr,sizeof(clientaddr));
	int addrsize=sizeof(clientaddr);
	
	
	//创建tcp套接字
	tcpsock=socket(AF_INET,SOCK_STREAM,0);
	if(tcpsock==-1)
	{
		perror("创建tcp套接字!n");
		return -1;
	}
	printf("旧的文件描述符:%dn",tcpsock);
	//设置端口重复使用
	int on=1;
	setsockopt(tcpsock,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(on));
	
	//绑定ip和端口号
	ret=bind(tcpsock,(struct sockaddr *)&bindaddr,sizeof(bindaddr));
	if(ret==-1)
	{
		perror("绑定失败!n");
		return -1;
	}
	//监听
	ret=listen(tcpsock,8);
	if(ret==-1)
	{
		perror("监听失败!n");
		return -1;
	}
	while(1)
	{
		//接收客户端的连接请求
		newsock=accept(tcpsock,(struct sockaddr *)&clientaddr,&addrsize);
		if(newsock==-1)
		{
			perror("接收客户端的连接请求失败!n");
			return -1;
		}
		printf("有新的客户端连接成功了,新的文件描述符:%dn",newsock);
		printf("有新的客户端连接成功了,他的IP地址是:%sn",inet_ntoa(clientaddr.sin_addr));
		printf("有新的客户端连接成功了,他的端口号是:%hun",ntohs(clientaddr.sin_port));
		//把文件描述符存放到链表中
		struct clientlist *newnode=malloc(sizeof(struct clientlist));
		newnode->sock=newsock;
		strcpy(newnode->ip,inet_ntoa(clientaddr.sin_addr));
		newnode->someport=ntohs(clientaddr.sin_port);
		INIT_LIST_HEAD(&(newnode->mypoint));
		//插入到链表的尾部
		list_add_tail(&(newnode->mypoint),&(myhead->mypoint));
		
		//立马新建线程接收这个客户端发送的信息
		pthread_create(&id,&myattr,routine,newnode);
	}
	
	
}

客户端

#include "myhead.h"


int tcpsock;
void *routine(void *arg)
{
	char buf[100];
	int ret;
	while(1)
	{
		bzero(buf,100);
		ret=read(tcpsock,buf,100);
		if(ret==0) //说明服务器断开连接
		{
			printf("服务器挂了!n");
			exit(-1); //结束整个进程
		}
		printf("服务器转发过来的信息是:%sn",buf);
	}
}
int main()
{
	pthread_t id;
	int ret;
	char buf[100];
	//定义ipv4地址结构体变量
	struct sockaddr_in bindaddr;
	bzero(&bindaddr,sizeof(bindaddr));
	bindaddr.sin_family=AF_INET;
	bindaddr.sin_addr.s_addr=htonl(INADDR_ANY);  //绑定客户端自己的ip地址
	bindaddr.sin_port=htons(10000); //绑定客户端自己的端口号
	
	//定义结构体变量存放对方(服务器)的ip和端口号
	struct sockaddr_in serveraddr;
	bzero(&serveraddr,sizeof(serveraddr));
	serveraddr.sin_family=AF_INET;
	serveraddr.sin_addr.s_addr=inet_addr("192.168.24.3");  //服务器的ip地址
	serveraddr.sin_port=htons(10086); //服务器的端口号
	//创建tcp套接字
	tcpsock=socket(AF_INET,SOCK_STREAM,0);
	if(tcpsock==-1)
	{
		perror("创建tcp套接字!n");
		return -1;
	}
	
	//设置端口重复使用
	int on=1;
	setsockopt(tcpsock,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(on));
	
	//绑定ip和端口号
	ret=bind(tcpsock,(struct sockaddr *)&bindaddr,sizeof(bindaddr));
	if(ret==-1)
	{
		perror("绑定失败!n");
		return -1;
	}
	
	//连接服务器
	ret=connect(sockfd,(struct sockaddr *)&serveraddr,sizeof(serveraddr));
	if(ret==-1)
	{
		perror("连接服务器!n");
		return -1;
	}
	//创建线程专门接收服务器的信息
	pthread_create(&id,NULL,routine,NULL);
	//发送信息给服务器
	while(1)
	{
		bzero(buf,100);
		printf("请输入要发送给服务器的信息,按照如下格式输入!n");
		printf("all:真实的信息--》群发!n");
		printf("端口号:真实的信息--》点播!n");
		scanf("%s",buf);
		write(sockfd,buf,strlen(buf));
	}
	close(tcpsock);
	return 0;
}

UDP单向通信
发送

#include "myhead.h"

int main()
{
	char buf[100];
	int ret;
	int udpsock;
	//定义ipv4地址结构体变量
	struct sockaddr_in bindaddr;
	bzero(&bindaddr,sizeof(bindaddr));
	bindaddr.sin_family=AF_INET;
	bindaddr.sin_addr.s_addr=htonl(INADDR_ANY);  //绑定自己的ip地址
	bindaddr.sin_port=htons(10086); //绑定自己的端口号

	struct sockaddr_in otheraddr;
	bzero(&otheraddr,sizeof(otheraddr));
	otheraddr.sin_family=AF_INET;
	otheraddr.sin_addr.s_addr=inet_addr("192.168.24.3"); //对方的ip
	otheraddr.sin_port=htons(20000); //对方的端口号
	 
	//创建udp套接字
	udpsock=socket(PF_INET,SOCK_DGRAM,0);
	if(udpsock==-1)
	{
		perror("创建udp套接字!n");
		return -1;
	}
	//设置端口重复使用
	int on=1;
	setsockopt(udpsock,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(on));
	
	//绑定ip和端口号
	ret=bind(udpsock,(struct sockaddr *)&bindaddr,sizeof(bindaddr));
	if(ret==-1)
	{
		perror("绑定失败!n");
		return -1;
	}
	
	//发送信息
	while(1)
	{
		bzero(buf,100);
		printf("请输入要发送的信息!n");
		scanf("%s",buf);
		sendto(udpsock,buf,strlen(buf),0,(struct sockaddr *)&otheraddr,sizeof(otheraddr));
	}
}	
	

接收

#include "myhead.h"

int main()
{
	char buf[100];
	char ip[16]={0};
	int ret;
	int udpsock;
	//定义ipv4地址结构体变量
	struct sockaddr_in bindaddr;
	bzero(&bindaddr,sizeof(bindaddr));
	bindaddr.sin_family=AF_INET;
	bindaddr.sin_addr.s_addr=htonl(INADDR_ANY);  //绑定自己的ip地址
	bindaddr.sin_port=htons(20000); //绑定自己的端口号

	struct sockaddr_in otheraddr;
	bzero(&otheraddr,sizeof(otheraddr));
	int size=sizeof(otheraddr);
	 
	//创建udp套接字
	udpsock=socket(PF_INET,SOCK_DGRAM,0);
	if(udpsock==-1)
	{
		perror("创建udp套接字!n");
		return -1;
	}
	//设置端口重复使用
	int on=1;
	setsockopt(udpsock,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(on));
	
	//绑定ip和端口号
	ret=bind(udpsock,(struct sockaddr *)&bindaddr,sizeof(bindaddr));
	if(ret==-1)
	{
		perror("绑定失败!n");
		return -1;
	}
	
	//接收信息
	while(1)
	{
		bzero(buf,100);
		recvfrom(udpsock,buf,100,0,(struct sockaddr *)&otheraddr,&size);
		printf("ip  %s  端口是 %hu 这个人发送的信息是:%sn",inet_ntop(AF_INET,&(otheraddr.sin_addr.s_addr),ip,sizeof(ip)),ntohs(otheraddr.sin_port),buf);
	}
}

UDP双向通信

#include "myhead.h"
int udpsock;
void *fun(void *arg)
{
	struct sockaddr_in addr;
	bzero(&addr,sizeof(addr));
	int size=sizeof(addr);
	char otherbuf[100];
	while(1)
	{
		bzero(otherbuf,100);
		recvfrom(udpsock,otherbuf,100,0,(struct sockaddr *)&addr,&size);
		printf("对方发送过来的信息是:%sn",otherbuf);
	}
}
int main()
{
	pthread_t id;
	char buf[100];
	int ret;
	
	//定义ipv4地址结构体变量
	struct sockaddr_in bindaddr;
	bzero(&bindaddr,sizeof(bindaddr));
	bindaddr.sin_family=AF_INET;
	bindaddr.sin_addr.s_addr=htonl(INADDR_ANY);  //绑定自己的ip地址
	bindaddr.sin_port=htons(10086); //绑定自己的端口号

	struct sockaddr_in otheraddr;
	bzero(&otheraddr,sizeof(otheraddr));
	otheraddr.sin_family=AF_INET;
	otheraddr.sin_addr.s_addr=inet_addr("192.168.24.3"); //对方的ip
	otheraddr.sin_port=htons(20000); //对方的端口号
	 
	//创建udp套接字
	udpsock=socket(PF_INET,SOCK_DGRAM,0);
	if(udpsock==-1)
	{
		perror("创建udp套接字!n");
		return -1;
	}
	//设置端口重复使用
	int on=1;
	setsockopt(udpsock,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(on));
	
	//绑定ip和端口号
	ret=bind(udpsock,(struct sockaddr *)&bindaddr,sizeof(bindaddr));
	if(ret==-1)
	{
		perror("绑定失败!n");
		return -1;
	}
	
	//线程专门接收信息
	pthread_create(&id,NULL,fun,NULL);
	//发送信息
	while(1)
	{
		bzero(buf,100);
		printf("请输入要发送的信息!n");
		scanf("%s",buf);
		sendto(udpsock,buf,strlen(buf),0,(struct sockaddr *)&otheraddr,sizeof(otheraddr));
	}
}	
	
#include "myhead.h"
int udpsock;
void *fun(void *arg)
{
	struct sockaddr_in otheraddr;
	bzero(&otheraddr,sizeof(otheraddr));
	otheraddr.sin_family=AF_INET;
	otheraddr.sin_addr.s_addr=inet_addr("192.168.24.3");  //对方的ip地址
	otheraddr.sin_port=htons(10086); //对方的端口号
	char buf[100];
	while(1)
	{
		bzero(buf,100);
		printf("请输入要发送的信息!n");
		scanf("%s",buf);
		sendto(udpsock,buf,strlen(buf),0,(struct sockaddr *)&otheraddr,sizeof(otheraddr));
	}
}
int main()
{
	pthread_t id;
	char buf[100];
	char ip[16]={0};
	int ret;
	
	//定义ipv4地址结构体变量
	struct sockaddr_in bindaddr;
	bzero(&bindaddr,sizeof(bindaddr));
	bindaddr.sin_family=AF_INET;
	bindaddr.sin_addr.s_addr=htonl(INADDR_ANY);  //绑定自己的ip地址
	bindaddr.sin_port=htons(20000); //绑定自己的端口号

	struct sockaddr_in otheraddr;
	bzero(&otheraddr,sizeof(otheraddr));
	int size=sizeof(otheraddr);
	 
	//创建udp套接字
	udpsock=socket(PF_INET,SOCK_DGRAM,0);
	if(udpsock==-1)
	{
		perror("创建udp套接字!n");
		return -1;
	}
	//设置端口重复使用
	int on=1;
	setsockopt(udpsock,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(on));
	
	//绑定ip和端口号
	ret=bind(udpsock,(struct sockaddr *)&bindaddr,sizeof(bindaddr));
	if(ret==-1)
	{
		perror("绑定失败!n");
		return -1;
	}
	//线程专门发送信息
	pthread_create(&id,NULL,fun,NULL);
	//接收信息
	while(1)
	{
		bzero(buf,100);
		recvfrom(udpsock,buf,100,0,(struct sockaddr *)&otheraddr,&size);
		printf("ip  %s  端口是 %hu 这个人发送的信息是:%sn",inet_ntop(AF_INET,&(otheraddr.sin_addr.s_addr),ip,sizeof(ip)),ntohs(otheraddr.sin_port),buf);
	}
}

UDP广播

在这里插入代码片#include "myhead.h"

int main()
{
	char buf[100];
	int ret;
	int udpsock;
	//定义ipv4地址结构体变量
	struct sockaddr_in bindaddr;
	bzero(&bindaddr,sizeof(bindaddr));
	bindaddr.sin_family=AF_INET;
	bindaddr.sin_addr.s_addr=htonl(INADDR_ANY);  //绑定自己的ip地址
	bindaddr.sin_port=htons(10086); //绑定自己的端口号

	struct sockaddr_in otheraddr;
	bzero(&otheraddr,sizeof(otheraddr));
	otheraddr.sin_family=AF_INET;
	otheraddr.sin_addr.s_addr=inet_addr("192.168.24.255"); //广播专用地址
	otheraddr.sin_port=htons(20000); //对方的端口号
	 
	//创建udp套接字
	udpsock=socket(PF_INET,SOCK_DGRAM,0);
	if(udpsock==-1)
	{
		perror("创建udp套接字!n");
		return -1;
	}
	//设置端口重复使用
	int on=1;
	setsockopt(udpsock,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(on));
	
	//绑定ip和端口号
	ret=bind(udpsock,(struct sockaddr *)&bindaddr,sizeof(bindaddr));
	if(ret==-1)
	{
		perror("绑定失败!n");
		return -1;
	}
	
	//设置套接字的属性为可以广播
	setsockopt(udpsock,SOL_SOCKET,SO_BROADCAST,&on,sizeof(on));
	
	//发送广播信息
	while(1)
	{
		bzero(buf,100);
		printf("请输入要发送广播的信息!n");
		scanf("%s",buf);
		sendto(udpsock,buf,strlen(buf),0,(struct sockaddr *)&otheraddr,sizeof(otheraddr));
	}
}	
	
```cpp
#include "myhead.h"

int main()
{
	char buf[100];
	char ip[16]={0};
	int ret;
	int udpsock;
	//定义ipv4地址结构体变量
	struct sockaddr_in bindaddr;
	bzero(&bindaddr,sizeof(bindaddr));
	bindaddr.sin_family=AF_INET;
	bindaddr.sin_addr.s_addr=htonl(INADDR_ANY);  //绑定自己的ip地址
	bindaddr.sin_port=htons(20000); //绑定自己的端口号

	struct sockaddr_in otheraddr;
	bzero(&otheraddr,sizeof(otheraddr));
	int size=sizeof(otheraddr);
	 
	//创建udp套接字
	udpsock=socket(PF_INET,SOCK_DGRAM,0);
	if(udpsock==-1)
	{
		perror("创建udp套接字!n");
		return -1;
	}
	//设置端口重复使用
	int on=1;
	setsockopt(udpsock,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(on));
	
	//绑定ip和端口号
	ret=bind(udpsock,(struct sockaddr *)&bindaddr,sizeof(bindaddr));
	if(ret==-1)
	{
		perror("绑定失败!n");
		return -1;
	}
	
	//接收信息
	while(1)
	{
		bzero(buf,100);
		recvfrom(udpsock,buf,100,0,(struct sockaddr *)&otheraddr,&size);
		printf("ip  %s  端口是 %hu 这个人发送的信息是:%sn",inet_ntop(AF_INET,&(otheraddr.sin_addr.s_addr),ip,sizeof(ip)),ntohs(otheraddr.sin_port),buf);
	}
}

send和 recv

#include "myhead.h"



int main()
{
	int tcpsock;
	int ret;
	char buf[100];
	//定义ipv4地址结构体变量
	struct sockaddr_in bindaddr;
	bzero(&bindaddr,sizeof(bindaddr));
	bindaddr.sin_family=AF_INET;
	bindaddr.sin_addr.s_addr=htonl(INADDR_ANY);  //绑定客户端自己的ip地址
	bindaddr.sin_port=htons(10000); //绑定客户端自己的端口号
	
	//定义结构体变量存放对方(服务器)的ip和端口号
	struct sockaddr_in serveraddr;
	bzero(&serveraddr,sizeof(serveraddr));
	serveraddr.sin_family=AF_INET;
	serveraddr.sin_addr.s_addr=inet_addr("192.168.24.3");  //服务器的ip地址
	serveraddr.sin_port=htons(20000); //服务器的端口号
	//创建tcp套接字
	tcpsock=socket(AF_INET,SOCK_STREAM,0);
	if(tcpsock==-1)
	{
		perror("创建tcp套接字!n");
		return -1;
	}
	//绑定ip和端口号
	ret=bind(tcpsock,(struct sockaddr *)&bindaddr,sizeof(bindaddr));
	if(ret==-1)
	{
		perror("绑定失败!n");
		return -1;
	}
	
	//连接服务器
	ret=connect(tcpsock,(struct sockaddr *)&serveraddr,sizeof(serveraddr));
	if(ret==-1)
	{
		perror("连接服务器!n");
		return -1;
	}
	
	//发送信息给服务器
	while(1)
	{
		bzero(buf,100);
		printf("请输入要发送给服务器的信息!n");
		scanf("%s",buf);
		send(tcpsock,buf,strlen(buf),0);
	}
	close(tcpsock);
	return 0;
}
#include "myhead.h"



int main(int argc,char **argv)
{
	int tcpsock;
	int newsock;
	int ret;
	char buf[100];
	//定义ipv4地址结构体变量
	struct sockaddr_in bindaddr;
	bzero(&bindaddr,sizeof(bindaddr));
	bindaddr.sin_family=AF_INET;
	bindaddr.sin_addr.s_addr=htonl(INADDR_ANY);  //绑定服务器自己的ip地址
	bindaddr.sin_port=htons(20000); //绑定服务器自己的端口号

	struct sockaddr_in clientaddr;
	bzero(&clientaddr,sizeof(clientaddr));
	int addrsize=sizeof(clientaddr);
	
	
	//创建tcp套接字
	tcpsock=socket(AF_INET,SOCK_STREAM,0);
	if(tcpsock==-1)
	{
		perror("创建tcp套接字!n");
		return -1;
	}
	printf("旧的文件描述符:%dn",tcpsock);
	
	//setsockopt(int sockfd, int level, int optname, const void *optval, socklen_t optlen);
	//绑定ip和端口号
	ret=bind(tcpsock,(struct sockaddr *)&bindaddr,sizeof(bindaddr));
	if(ret==-1)
	{
		perror("绑定失败!n");
		return -1;
	}
	//监听
	ret=listen(tcpsock,8);
	if(ret==-1)
	{
		perror("监听失败!n");
		return -1;
	}
	//接收客户端的连接请求
	newsock=accept(tcpsock,(struct sockaddr *)&clientaddr,&addrsize);
	if(newsock==-1)
	{
		perror("接收客户端的连接请求失败!n");
		return -1;
	}
	printf("新的文件描述符:%dn",newsock);
	//接收信息
	while(1)
	{
		bzero(buf,100);
		//ret=recv(newsock,buf,100,0);
		ret=recv(newsock,buf,100,MSG_WAITALL); //强行要求recv按照100个字节接收数据,没有100个字节就阻塞等待
		printf("recv的返回值是:%dn",ret);
		printf("客户端发送给我的信息是:%sn",buf);
	}
}
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1003997.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号