udp服务器客户端
服务器
#include <myhead.h>
#define ERR_MSG(msg) do{\
printf("__%d__\n",__LINE__);\
perror(msg);\
}while(0)
#define IP "192.168.10.147"
#define PORT 6666
int main(int argc, const char *argv[])
{
//创建报式套接字
int sfd = socket(AF_INET,SOCK_DGRAM,0);
if (sfd < 0)
{
ERR_MSG("socket");
return -1;
}
printf("sfd = %d\n",sfd);
//填充服务器的地址信息结构体
struct sockaddr_in sin;
sin.sin_family = AF_INET;
sin.sin_port = htons(PORT);
sin.sin_addr.s_addr = inet_addr(IP);
//绑定服务器的IP和端口号
if (bind(sfd,(struct sockaddr *)&sin,sizeof(sin)) < 0)
{
ERR_MSG("bind");
return -1;
}
printf("bind success\n");
//存储数据包的信息
struct sockaddr_in cin;
socklen_t addrlen = sizeof(cin);
//定义容器
char buf[128] = "";
while (1)
{
//接受数据
bzero(buf,sizeof(buf));
if (recvfrom(sfd,buf,sizeof(buf),0,(struct sockaddr *)&cin,&addrlen) < 0)
{
ERR_MSG("recvfrom");
return -1;
}
printf("[%s : %d] : %s\n",inet_ntoa(cin.sin_addr),ntohs(cin.sin_port),buf);
//发送数据
strcat(buf,"*_*");
if (sendto(sfd,buf,sizeof(buf),0,(struct sockaddr *)&cin,sizeof(cin)) < 0)
{
ERR_MSG("sendto");
return -1;
}
printf("send success\n");
}
//关闭套接字
close(sfd);
return 0;
}
客户端
#include <myhead.h>
#define ERR_MSG(msg) do{\
printf("__%d__\n",__LINE__);\
perror(msg);\
}while(0)
#define IP "192.168.10.147"
#define PORT 6666
int main(int argc, const char *argv[])
{
//创建报式套接字
int cfd = socket(AF_INET,SOCK_DGRAM,0);
if (cfd < 0)
{
ERR_MSG("socket");
return -1;
}
printf("cfd = %d\n",cfd);
//填充服务器的地址信息结构体
struct sockaddr_in sin;
sin.sin_family = AF_INET;
sin.sin_port = htons(PORT);
sin.sin_addr.s_addr = inet_addr(IP);
//存储数据包的信息
struct sockaddr_in cin;
socklen_t addrlen = sizeof(cin);
//定义容器
char buf[128] = "";
while (1)
{
//发送数据
bzero(buf,sizeof(buf));
printf("请输入>>>");
fgets(buf,sizeof(buf),stdin);
buf[strlen(buf)-1] = 0;
if (sendto(cfd,buf,sizeof(buf),0,(struct sockaddr *)&sin,sizeof(sin)) < 0)
{
ERR_MSG("sendto");
return -1;
}
printf("send success\n");
//接受数据
bzero(buf,sizeof(buf));
if (recvfrom(cfd,buf,sizeof(buf),0,(struct sockaddr *)&cin,&addrlen) < 0)
{
ERR_MSG("recvfrom");
return -1;
}
printf("[%s : %d] : %s\n",inet_ntoa(cin.sin_addr),ntohs(cin.sin_port),buf);
}
//关闭套接字
close(cfd);
return 0;
}
tftp下载代码
#include <myhead.h>
#define ERR_MSG(msg) do{\
fprintf(stderr, "__%d__", __LINE__);\
perror(msg);\
} while (0)
#define IP "192.168.10.125"
#define PORT 69
int do_download(int sfd, struct sockaddr_in sin);
int main(int argc, const char *argv[])
{
//创建流式套接字
int sfd = socket(AF_INET, SOCK_DGRAM, 0);
if (sfd < 0)
{
ERR_MSG("socket");
return -1;
}
printf("sfd = %d\n", sfd);
struct sockaddr_in sin;
sin.sin_family = AF_INET;
sin.sin_port = htons(PORT);
sin.sin_addr.s_addr = inet_addr(IP);
char c = 0;
while (1)
{
printf("********************\n");
printf("*******1.上传*******\n");
printf("*******2.下载*******\n");
printf("*******3.退出*******\n");
printf("********************\n");
printf("请输入>>>");
c = getchar();
while (getchar() != 10);
switch (c)
{
case '1':
break;
case '2':
do_download(sfd, sin);
break;
case '3':
goto END;
default:
printf("输入错误,请重新输入\n");
}
}
END:
//关闭套接字
close(sfd);
return 0;
}
int do_download(int sfd, struct sockaddr_in sin)
{
char name[20];
printf("请输入文件名:");
scanf("%s", name);
while (getchar() != 10);
//组下载请求协议包
char buf[516] = "";
unsigned short *ptr1 = (unsigned short *)buf;
*ptr1 = htons(1); //操作码,下载
char *ptr2 = buf + 2;
strcpy(ptr2, name);
char *ptr3 = ptr2 + strlen(name);
*ptr3 = 0;
char *ptr4 = ptr3 + 1;
strcpy(ptr4, "octet");
int size = 2 + 1 + 1 + strlen(ptr2) + strlen(ptr4);
//发送请求给服务器
if (sendto(sfd, buf, size, 0, (struct sockaddr *)&sin, sizeof(sin)) < 0)
{
ERR_MSG("sendto");
return -1;
}
printf("发送下载请求给服务器成功\n");
//设置文件保存路径
int fd;
if((fd = open(name, O_WRONLY | O_CREAT | O_APPEND, 0666)) < 0)
{
ERR_MSG("open");
return -1;
}
socklen_t addrlen = sizeof(sin);
ssize_t res = 0;
short num = 1;
while (1)
{
//接收数据包
bzero(buf, sizeof(buf));
res = recvfrom(sfd, buf, sizeof(buf), 0, (struct sockaddr *)&sin, &addrlen);
if ( res < 0)
{
ERR_MSG("recvfrom");
return -1;
}
unsigned short *data = (unsigned short *)buf;
if(3 == ntohs(*data))
{
if (htons(num) == *((unsigned short *)(buf + 2))) //块编号,供ACK使用
{
//将数据写入到本地文件
write(fd, buf + 4, res - 4);
}
//回复ACK
bzero(buf, sizeof(buf));
unsigned short *p = (unsigned short *)buf;
*p = htons(4); //ACK操作码
*(p + 1) = htons(num);
if (sendto(sfd, buf, 4, 0, (struct sockaddr *)&sin, addrlen) < 0)
{
ERR_MSG("sendto");
return -1;
}
//判断数据是否小于512,若小于512,则传输结束
if (res < 516)
{
printf("文件拷贝完毕\n");
break;
}
num++;
}
}
close(fd);
return 0;
}