广播,组播代码重新写一遍
广播
组播
#include <myhead.h>
#define PORT 8888
#define IP "224.1.2.3"
int main(int argc, const char *argv[])
{
//创建报式套接字
int sfd = socket(AF_INET,SOCK_DGRAM,0);
if(sfd == -1)
PRI_ERR("socket err");
//填充接收方的地址信息
struct sockaddr_in rin;
rin.sin_family = AF_INET;
rin.sin_port = htons(PORT);
rin.sin_addr.s_addr = inet_addr(IP);
//发送
char buf[128]="hi";
while(1)
{
if(sendto(sfd,buf,sizeof(buf),0,(struct sockaddr*)&rin,sizeof(rin))==-1)
PRI_ERR("send err");
}
//关闭套接字
close(sfd);
return 0;
}
#include <myhead.h>
#define IP "224.1.2.3"
#define PORT 8888
int main(int argc, const char *argv[])
{
//创建报式套接字
int rfd = socket(AF_INET,SOCK_DGRAM,0);
if(rfd == -1)
PRI_ERR("socket err");
//加入组
struct ip_mreqn mq;
mq.imr_multiaddr.s_addr = inet_addr(IP);
mq.imr_address.s_addr = inet_addr("192.168.123.140");
mq.imr_ifindex = 2;
socklen_t addlen = sizeof(mq);
if(setsockopt(rfd,IPPROTO_IP,IP_ADD_MEMBERSHIP,&mq,addlen)==-1)
PRI_ERR("add err");
//填充接收方地址信息,用组播ip和组播的port:自定义
struct sockaddr_in rin;
rin.sin_family = AF_INET;
rin.sin_port = htons(PORT);
rin.sin_addr.s_addr = inet_addr(IP);
//bind绑定
if(bind(rfd,(struct sockaddr*)&rin,sizeof(rin))==-1)
PRI_ERR("bind err");
printf("bind success\n");
//接收
char buf[128]="";
while(1)
{
bzero(buf,sizeof(buf));
if(recv(rfd,buf,sizeof(buf),0)==-1)
PRI_ERR("recv err");
printf("%s\n",buf);
}
//关闭套接字
close(rfd);
return 0;
}
多进程通过模型自己写一遍
#include <myhead.h>
#define IP "192.168.123.140"
#define PORT 8080
void send_recv(int nfd);
void sighandel(int signo)
{
while(waitpid(-1,NULL,WNOHANG)>0);
}
int main(int argc, const char *argv[])
{
//绑定子进程结束信号
signal(SIGCHLD,sighandel);
//创建报式套接字
int sfd = socket(AF_INET,SOCK_STREAM,0);
if(sfd == -1)
PRI_ERR("socket err");
//绑定地址信息
struct sockaddr_in sin;
sin.sin_family = AF_INET;
sin.sin_port = htons(PORT);
sin.sin_addr.s_addr = inet_addr(IP);
if(bind(sfd,(struct sockaddr*)&sin,sizeof(sin))==-1)
PRI_ERR("bind err");
//切换监听模式
if(listen(sfd,648)==-1)
PRI_ERR("listen err");
char buf[128] = "";
int nfd=-1;
socklen_t addlen = sizeof(sin);
while(1)
{
//循环接收客户端
nfd = accept(sfd,(struct sockaddr*)&sin,&addlen);
if(nfd == -1)
PRI_ERR("accept err");
pid_t pid = fork();
if(pid<0)
PRI_ERR("pid err");
else if(pid>0)
{
close(nfd);
}
else
{
//与客户端收发消息
close(sfd);
send_recv(nfd);
exit(EXIT_SUCCESS);
}
}
//关闭套接字文件描述符
return 0;
}
void send_recv(int nfd)
{
char buf[128] = "";
while(1)
{
bzero(buf,sizeof(buf));
int ret = recv(nfd,buf,sizeof(buf),0);
if(ret==0)
PRI_ERR("客户端下线");
else if(ret == -1)
PRI_ERR("recv err");
else
printf("recv success\n");
strcat(buf,"*/");
if(send(nfd,buf,sizeof(buf),0)==-1)
PRI_ERR("send err");
printf("send success\n");
}
close(nfd);
}
多线程代码写一遍,能否将newfd定义成全局(不行,找原因)
#define LIP "192.168.123.140"
#define LPORT 8080
void* task(void* arg)
{
int nfd = *(int *)arg;
char buf[128] = "";
//子线程实现收发消息
while(1)
{
bzero(buf,sizeof(buf));
int ret = recv(nfd,buf,sizeof(buf),0);
if(ret==-1)
{
perror("recv err");
continue;
}
else if(ret == 0)
printf("客户端下线i\n");
else
printf("接收到消息:%s\n",buf);
bzero(buf,sizeof(buf));
strcpy(buf,"i have got you msg");
if(send(nfd,buf,sizeof(buf),0)==-1)
{
perror("send err");
continue;
}
}
pthread_exit(NULL);
}
int main(int argc, const char *argv[])
{
//创建套接字文件描述符
int sfd = socket(AF_INET,SOCK_STREAM,0);
if(sfd == -1)
PRI_ERR("socket err");
//绑定本地ip和端口
struct sockaddr_in sin;
sin.sin_family = AF_INET;
sin.sin_port = htons(LPORT);
sin.sin_addr.s_addr = inet_addr(LIP);
if(bind(sfd,(struct sockaddr*)&sin,sizeof(sin))==-1)
PRI_ERR("bind err");
//设置监听模式
if(listen(sfd,648)==-1)
PRI_ERR("listen err");
while(1)
{
struct sockaddr_in cin;
socklen_t addlen = sizeof(cin);
//循环accept
int nfd = accept(sfd,(struct sockaddr*)&cin,&addlen);
if(nfd == -1)
PRI_ERR("accept err");
printf("%s:%d\t:accept success\n",inet_ntoa(cin.sin_addr),ntohs(cin.sin_port));
//创建子线程
pthread_t tid;
if(pthread_create(&tid,NULL,task,&nfd))
{
perror("create err");
continue;
}
}
//关闭文件描述符
return 0;
}
上传下载写完
#include <myhead.h>
#define IP "192.168.174.1"
#define PORT 69
void upload(int ufd,struct sockaddr_in sin);
void download(int ufd,struct sockaddr_in sin);
int main(int argc, const char *argv[])
{
//创建报式套接字
int ufd = socket(AF_INET,SOCK_DGRAM,0);
if(ufd==-1)
PRI_ERR("socket err");
//创建地址信息结构体,写入服务器信息
struct sockaddr_in sin;
sin.sin_family = AF_INET;
sin.sin_port = htons(PORT);
sin.sin_addr.s_addr = inet_addr(IP);
while(1)
{
printf("************************\n");
printf("*******1: 上传**********\n");
printf("*******2:下载**********\n");
printf("*******3:退出**********\n");
printf("请输入:");
char c = getchar();
while(getchar()!='\n');
switch(c)
{
case '1':
{
upload(ufd,sin);
}break;
case '2':
{
download(ufd,sin);
}break;
case '3':
{
exit(EXIT_SUCCESS);
}break;
default:printf("error\n");break;
}
}
close(ufd);
return 0;
}
void upload(int ufd,struct sockaddr_in sin)
{
//写入请求数据包
char buf[516] = "";
short *p = (short *)buf;
*p = htons(2);
char* p1 = (char*)(p+1);
printf("请输入你要上传的文件:");
scanf("%s",p1);
while(getchar()!='\n');
char* p2 = p1+strlen(p1)+1;
strcpy(p2,"octet");
char *p3 = p2+strlen(p2)+1;
strcpy(p3,"blksize");
size_t bufsize = 5+strlen(p1)+strlen(p2)+strlen(p3);
//发送写入请求
if(sendto(ufd,buf,bufsize,0,(struct sockaddr*)&sin,sizeof(sin))==-1)
PRI_ERR("send err");
//打开要发送的文件
int fd = open(p1,O_RDONLY);
if(fd == -1)
PRI_ERR("fd err");
int i = 0;
//循环发送数据包
while(1)
{
bzero(buf,sizeof(buf));
short *q = (short*)buf;
*q = htons(3);
short *q1 = q+1;
*q1 = htons(i++);
char *q2 = (char*)(q1+1);
read(fd,q2,512);
int datasize = 0;
if((datasize = sendto(ufd,buf,sizeof(buf),0,(struct sockaddr*)&sin,sizeof(sin)))==-1)
PRI_ERR("send err");
if(datasize<516)
break;
}
}
void download(int ufd,struct sockaddr_in sin)
{
//组包
char buf[516]="";
short* p1 = (short* )buf;
*p1 = htons(1);
char *p2 = (char*)(p1+1);
//获取文件名
printf("请输入文件名:");
scanf("%s",p2);
while(getchar()!='\n');
char* p3 = p2+strlen(p2)+1;
strcpy(p3,"octet");
size_t bufsize = 4+strlen(p2)+strlen(p3);
//发送下载请求
if(sendto(ufd,buf,bufsize,0,(struct sockaddr*)&sin,sizeof(sin))==-1)
PRI_ERR("send err");
//打开一个用于写入的文件
int fd = open(p2,O_WRONLY|O_CREAT|O_APPEND,0664);
if(fd == -1)
PRI_ERR("fd err");
//循环接收数据,发送ACK,判断数据大小
while(1)
{
//接受数据
bzero(buf,sizeof(buf));//将buf清空
socklen_t addlen = sizeof(sin);
int datasize = 0;
if((datasize = recvfrom(ufd,buf,sizeof(buf),0,(struct sockaddr*)&sin,&addlen))==-1)
PRI_ERR("recvfrom err");
if(datasize<516)//判断数据的大小
break;
char* data = buf+4;
write(fd,data,512);
short *id = (short*)buf;
short num = *(id+1);
id +=1;
//组ACK包
bzero(buf,sizeof(buf));
short *A = (short*)buf;
*A = htons(4);
*(A+1) = num;
//将ACK发给服务器
if(sendto(ufd,buf,4,0,(struct sockaddr*)&sin,sizeof(sin))==-1)
PRI_ERR("send err");
}
close(fd);
return;
}