(1)UDP协议搭建流程服务器和客户端
服务器:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#define ERRORLINE(msg) do{fprintf(stderr,"line:%d\n",__LINE__);perror(msg);}while(0);
#define IP "192.168.0.7"
int main(int argc, const char *argv[])
{
//1.socket创建报式套接字
int fd = socket(AF_INET,SOCK_DGRAM,0);
if(fd<0)
{
ERRORLINE("socket");
return -1;
}
//2.bind 绑定,ip地址和端口号
struct sockaddr_in sin;
sin.sin_family = AF_INET;
sin.sin_port = htons(7777);
sin.sin_addr.s_addr = inet_addr(IP);
if(bind(fd,(struct sockaddr *)&sin,sizeof(sin))<0)
{
ERRORLINE("bind");
return -1;
}
/************************************/
//建立connect函数连接对应交互端端口
struct sockaddr_in din;
din.sin_family = AF_INET;
din.sin_port = htons(6666);
din.sin_addr.s_addr = inet_addr("192.168.0.7");
if(connect(fd,(struct sockaddr*)&din,sizeof(din))<0)
{
ERRORLINE("connect");
return -1;
}
printf("连接成功\n");
/************************************/
//3.recvfrom 接受客户端信息
char buf[128]={0};
char suf[128]={0};
struct sockaddr_in cin;
socklen_t len = sizeof(cin);
ssize_t n = 0;
while(1)
{
bzero(buf,sizeof(buf));
n = recvfrom(fd,buf,sizeof(buf),0,(struct sockaddr*)&cin,&len);
if(n<0)
{
ERRORLINE("recvfrom");
return -1;
}
printf("[%s : %d]:%s\n",inet_ntoa(cin.sin_addr), ntohs(cin.sin_port), buf);
//4.sendto 发送机制
strcpy(suf,"hello");
n = sendto(fd,suf,sizeof(suf),0,(struct sockaddr *)&cin,sizeof(cin));
if(n<0)
{
ERRORLINE("sendto");
return -1;
}
}
//5.关闭套接字
close(fd);
return 0;
}
客户端:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#define ERRORLINE(msg) do{fprintf(stderr,"line:%d\n",__LINE__);perror(msg);}while(0);
#define IP "192.168.0.7"
int main(int argc, const char *argv[])
{
//1.socket创建报式套接字
int fd = socket(AF_INET,SOCK_DGRAM,0);
if(fd<0)
{
ERRORLINE("socket");
return -1;
}
//2.bind 绑定,ip地址和端口号
struct sockaddr_in sin;
sin.sin_family = AF_INET;
sin.sin_port = htons(7777);
sin.sin_addr.s_addr = inet_addr(IP);
/* if(bind(fd,(struct sockaddr *)&sin,sizeof(sin))<0)
{
ERRORLINE("bind");
return -1;
}
*/ //3.recvfrom 接受客户端信息
char buf[128]={0};
char suf[128]={0};
struct sockaddr_in cin;
socklen_t len = sizeof(cin);
ssize_t n = 0;
while(1)
{
printf("请发送信息:");
memset(suf,0,sizeof(suf));
fgets(suf,sizeof(buf),stdin);
suf[strlen(suf)-1]='\0';
n = sendto(fd,suf,sizeof(suf),0,(struct sockaddr *)&sin,sizeof(sin));
if(n<0)
{
ERRORLINE("sendto");
return -1;
}
bzero(buf,sizeof(buf));
n = recvfrom(fd,buf,sizeof(buf),0,(struct sockaddr*)&cin,&len);
if(n<0)
{
ERRORLINE("recvfrom");
return -1;
}
printf("[%s : %d]:%s\n",inet_ntoa(cin.sin_addr), ntohs(cin.sin_port), buf);
//4.sendto 发送机制
}
//5.关闭套接字
close(fd);
return 0;
}
(2)基于UDP的上传和下载
下载:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <pthread.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <fcntl.h>
#define ERRORLINE(msg) do{fprintf(stderr,"line:%d\n",__LINE__);perror(msg);}while(0);
#define IP "192.168.0.114"
int main(int argc, const char *argv[])
{
int file_fd;
//1.创建套接字
int fd = socket(AF_INET,SOCK_DGRAM,0);
if(fd<0)
{
ERRORLINE("socket");
return -1;
}
//2.确定服务器端口
struct sockaddr_in sin;
sin.sin_family = AF_INET;
sin.sin_port = htons(69);
sin.sin_addr.s_addr = inet_addr(IP);
/* char buf[516] = {0};
short *p = (short *)buf;
char *p1 = buf+2;
char *p2 = buf+7;
char *p3 = buf+8;
char *p4 = buf+13;
*p=htons(1);
strcpy(p1,"5.png");
*p2 = 0;
strcpy(p3,"octet");
*p4 = 0;
*/
//4.实现功能
printf("****1下载****\n");
printf("****2上传****\n");
printf("****3待机****\n");
printf("请选择功能:");
int choose = 0;
char a = 0;
char arr[64] = {0};
scanf("%d",&choose);
getchar();
while(1)
{
if(choose == 1)
{
a = 0x01;
printf("请输入要下载的文件名:");
fgets(arr,sizeof(arr),stdin);
arr[strlen(arr)-1]='\0';
//建立读写文件接受数据
file_fd = open(argv[1],O_RDWR|O_CREAT|O_TRUNC,0666);
if(file_fd<0)
{
ERRORLINE("open");
return -1;
}
break;
}
else if(choose == 2)
{
a = 0x02;
printf("请输入要上传的文件名:");
fgets(arr,sizeof(arr),stdin);
arr[strlen(arr)-1]='\0';
file_fd = open(argv[1],O_RDONLY);
if(file_fd<0)
{
ERRORLINE("open");
return -1;
}
break;
}
}
//组建发送读写指令协议包
char buf[516] = {0};
int size = sprintf(buf,"%c%c%s%c%s%c",0x00,a,arr,0,"octet",0);
//遍历组装的包
/*
for(int i=0; i<size; i++)
{
printf("buf[%d]:%c | %d\n",i,buf[i],buf[i]);
}
*/
//发送下载/上传请求数据包
int n = 0;
n = sendto(fd,buf,size,0,(struct sockaddr *)&sin,sizeof(sin));
if(n<0)
{
ERRORLINE("sendto");
return -1;
}
struct sockaddr_in cin; //地址结构体等待接收返回信息
socklen_t len = sizeof(cin);
pid_t pid = fork();
if(pid<0)
{
ERRORLINE("pid");
return -1;
}
else if(pid == 0)
{
while(1)
{
bzero(buf,sizeof(buf));
n=recvfrom(fd,buf,sizeof(buf),0,(struct sockaddr*)&cin,&len);
if(n<0)
{
ERRORLINE("recvfrom");
return -1;
}
if(n<512)
{
exit(EXIT_SUCCESS);
}
//保存2字节的块编号或差错码
char buf_2 = buf[2];
char buf_3 = buf[3];
/* for(int i=0; i<n; i++)
{
printf("buf[%d]:%c | %d\n",i,buf[i],buf[i]);
}
*/
// printf("%d\n",ntohs(cin.sin_port));
if(buf[1] != 3)
{
ERRORLINE("recvfrom");
printf("差错码:%c%c\n",buf[1],buf[2]);
for(int j = 4; buf[j] != '\0'; j++)
{
printf("%c",buf[j]);
}
fflush(stdout);
exit(0);
}
else
{
for(int i=4;i<n;i++)
{
write(file_fd,&buf[i],1);
}
}
bzero(buf,sizeof(buf));
size = sprintf(buf,"%c%c%c%c",0x00,0x04,buf_2,buf_3);
/* for(int i=0; i<size; i++)
{
printf("buf[%d]:%c | %d\n",i,buf[i],buf[i]);
}
*/
n = sendto(fd,buf,size,0,(struct sockaddr*)&cin,sizeof(cin));
if(n<0)
{
ERRORLINE("sendto");
return -1;
}
}
}
else
{
waitpid(-1,NULL,0);
printf("下载完成\n");
}
close(file_fd);
close(fd);
return 0;
}