【LINUX/UNIX网络编程】之使用SOCKET进行UDP编程
先看任务需求:
实验二 UDP数据发送与接收
【实验目的】
1、熟练掌握套接字函数的使用方法。
2、应用套接字函数完成基本UDP通讯,实现服务器与客户端的文件传送
【实验学时】
4学时
【实验内容】
要求:
(1)客户可以从服务器下载文件、或向服务器上传文件。
(2)客户可向服务器发送多种指令:DOWNLOAD、UPLOAD、YES、NO、START、END、SHUTDOWN、CONTENT、OKDOWLOAD格式:DOWLOAD [filename]表示从服务器下载filename文件,如果服务器存在该文件,返回YES,否则返回NO;客户接收如果是YES,可发送START表示开始下载,之后,服务器将文件传送给客户,客户接收并保存;UPLOAD格式:UPLOAD [filename]表示向服务器上传filename文件,服务器发送NO表示拒绝接收。服务器发送START表示开始传送,之后向服务器传输文件;END:表示文件传送结束SHUTDOWN:表示通讯结束,双方退出。
先画一下流程图方便理顺思路:



下面上代码:
1.定义了一个protocol结构体方便传输信息和信息校验等;
#ifndef _protocol
#define _protocol #define INFOLEN 1000
#define SHUTDOWN 0
#define DOWNLOAD 1
#define UPLOAD 2
#define YES 3
#define NO 4
#define START 5
#define END 6
#define CONTENT 7
#define OK 8 struct protocol
{
int command;
int len; //length of buf
int no;
char buf[INFOLEN];
};
#endif
2.客户端程序:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <fcntl.h>
#include <sys/stat.h>
#include "protocol.h" /*-----------------------变量声明区------------------*/
int socketfd;
int addrlen;
struct sockaddr_in server;
struct protocol sentbuf;
struct protocol recvbuf;
int num;
char ip[];
int port;
int choice;
char filename[];
/*------------------------函数声明区------------------*/
void ShowMenu();
void DownLoad();
void UpLoad();
void ShutDown(); int main() { /*-------------create UDP socket------------*/
if((socketfd = socket(AF_INET,SOCK_DGRAM,)) == -){
perror("socket error\n");
exit();
} /*-----------------IO-----------------------*/
printf("Please input the ip:\n");
scanf("%s",ip);
printf("Please input the port:\n");
scanf("%d",&port); /*--------------------recvfrom and sendto----------*/
bzero(&server,sizeof(server));
server.sin_family = AF_INET;
server.sin_port = htons(port);
server.sin_addr.s_addr = inet_addr(ip);
addrlen = sizeof(server); /*--------------------调试信息---------------------------
recvbuf.command = DOWNLOAD;
recvbuf.no =0;
printf("input the message:\n");
scanf("%s",recvbuf.buf);
recvbuf.len = strlen(recvbuf.buf);
sendto(socketfd,&recvbuf,sizeof(recvbuf),0,(struct sockaddr *)&server,sizeof(server)); */ while (){
ShowMenu();
scanf("%d",&choice);
if(choice == SHUTDOWN){
ShutDown();
break;
}
else if(choice == DOWNLOAD){
DownLoad();
}
else if(choice == UPLOAD){
UpLoad();
}
else{
printf("Please make a right choice!\n");
}
} /*-----------------close------------------------*/
close(socketfd);
return ;
} void ShowMenu(){
printf("=====================================\n");
printf(" Please make a choice: \n");
printf(" 0: ||shutdown|| \n");
printf(" 1: ||download|| \n");
printf(" 2: || upload || \n");
printf("=====================================\n");
}
void DownLoad(){
bzero(&recvbuf,sizeof(recvbuf));
bzero(&sentbuf,sizeof(sentbuf));
bzero(filename,sizeof(filename));
printf("Please input the file name:\n");
scanf("%s",sentbuf.buf);
sentbuf.command = DOWNLOAD;
sendto(socketfd,&sentbuf,sizeof(sentbuf),,(struct sockaddr *)&server,sizeof(server));
bcopy(sentbuf.buf,filename,strlen(sentbuf.buf));
recvfrom(socketfd,&recvbuf,sizeof(recvbuf),,(struct sockaddr *)&server,&addrlen);
if(recvbuf.command == YES){
printf("YES!\n");
printf("Start to transmission!\n");
sentbuf.command = START;
sendto(socketfd,&sentbuf,sizeof(sentbuf),,(struct sockaddr *)&server,sizeof(server));
int no =;
int fd =open(filename,O_CREAT | O_TRUNC |O_WRONLY,);
if(fd < ){
perror("create file error\n");
exit();
}
bzero(&recvbuf,sizeof(recvbuf));
while((num = recvfrom(socketfd,&recvbuf,sizeof(recvbuf),,(struct sockaddr *)&server,&addrlen)) >){
if(recvbuf.command == CONTENT){
if(no == recvbuf.no){
write(fd,recvbuf.buf,recvbuf.len);
//printf("kkk%s\n",recvbuf.buf );
no++;
bzero(&recvbuf,sizeof(recvbuf));
}
else{
perror("The file no is not same.Some message is missed! error occured! \n");
break;
}
}
if(recvbuf.command == END){
close(fd);
printf("transmission is successful!\n");
break;
}
}
}
else if(recvbuf.command ==NO){
perror("NO such file on server!\n");
}
else{
perror("recvbuf.command error\n");
exit();
}
}
void UpLoad(){
bzero(&recvbuf,sizeof(recvbuf));
bzero(&sentbuf,sizeof(sentbuf));
bzero(filename,sizeof(filename));
printf("Please input the file name:\n");
scanf("%s",sentbuf.buf);
sentbuf.command = UPLOAD;
sendto(socketfd,&sentbuf,sizeof(sentbuf),,(struct sockaddr *)&server,sizeof(server));
bcopy(sentbuf.buf,filename,strlen(sentbuf.buf));
//判断要传输的文件是否存在
int fd;
fd = open(filename,O_RDONLY);
if(fd < ){
perror("The file you want to trans is not exist!\n");
exit();
}
recvfrom(socketfd,&recvbuf,sizeof(recvbuf),,(struct sockaddr *)&server,&addrlen);
if(recvbuf.command == START){
int no =;
while((num = read(fd,sentbuf.buf,INFOLEN)) >){
sentbuf.no = no;
sentbuf.command = CONTENT;
sentbuf.len = strlen(sentbuf.buf);
sendto(socketfd,&sentbuf,sizeof(sentbuf),,(struct sockaddr *)&server,sizeof(server));
no++;
bzero(&sentbuf,sizeof(sentbuf));
}
bzero(&sentbuf,sizeof(sentbuf));
sentbuf.command = END;
sendto(socketfd,&sentbuf,sizeof(sentbuf),,(struct sockaddr *)&server,sizeof(server));
}
else if(recvbuf.command == NO){
printf("not transmission\n");
printf("The file is exist!\n");
}
else {
perror("error! wrong choice!\n");
}
} void ShutDown(){
printf("client is shutdown now!\n");
bzero(&sentbuf,sizeof(sentbuf));
sentbuf.command == SHUTDOWN;
sendto(socketfd,&sentbuf,sizeof(sentbuf),,(struct sockaddr *)&server,sizeof(server));
}
3.服务器端程序:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <fcntl.h>
#include <sys/stat.h>
#include "protocol.h" /*-----------------------变量声明区------------------*/
int socketfd;
int addrlen;
struct sockaddr_in server;
struct sockaddr_in client;
struct protocol sentbuf;
struct protocol recvbuf;
int num;
char ip[];
int port;
int choice; int main(){ /*-------------create UDP socket------------*/
if((socketfd = socket(AF_INET,SOCK_DGRAM,)) == -){
perror("socket error\n");
exit();
} /*-----------------IO-----------------------*/
printf("Please input the ip:\n");
scanf("%s",ip);
printf("Please input the port:\n");
scanf("%d",&port); /*-----------------bind----------------------*/
bzero(&server,sizeof(server));
server.sin_family = AF_INET;
server.sin_port = htons(port);
server.sin_addr.s_addr = inet_addr(ip);
if (bind(socketfd,(struct sockaddr *)&server,sizeof(server)) == -){
perror("bind error\n");
exit();
} /*---------------------调试信息------------
addrlen = sizeof(client);
recvfrom(socketfd,&recvbuf,sizeof(recvbuf),0,(struct sockaddr *)&client,&addrlen);
num = strlen(recvbuf.buf);
recvbuf.buf[num] = '\0';
printf("command %d\n",recvbuf.command );
printf("len %d\n",recvbuf.len );
printf("no %d\n", recvbuf.no);
printf("buf %s\n",recvbuf.buf ); */ addrlen = sizeof(client);
while(){
bzero(&recvbuf,sizeof(recvbuf));
num =recvfrom(socketfd,&recvbuf,sizeof(recvbuf),,(struct sockaddr *)&client,&addrlen);
choice = recvbuf.command;
if(choice == DOWNLOAD){
char buf[];
int fd;
fd = open((recvbuf.buf),O_RDONLY);
if(fd <){
sentbuf.command = NO;
sendto(socketfd,&sentbuf,sizeof(sentbuf),,(struct sockaddr *)&client,sizeof(client));
printf("no such file!\n");
exit();
}
else{
sentbuf.command = YES;
sendto(socketfd,&sentbuf,sizeof(sentbuf),,(struct sockaddr *)&client,sizeof(client));
recvfrom(socketfd,&recvbuf,sizeof(recvbuf),,(struct sockaddr *)&client,&addrlen);
if(recvbuf.command == START){
int no =;
while((num = read(fd,sentbuf.buf,INFOLEN)) >){
sentbuf.no = no;
sentbuf.command = CONTENT;
sentbuf.len = strlen(sentbuf.buf);
sendto(socketfd,&sentbuf,sizeof(sentbuf),,(struct sockaddr *)&client,sizeof(client));
no++;
bzero(&sentbuf,sizeof(sentbuf));
}
bzero(&sentbuf,sizeof(sentbuf));
sentbuf.command = END;
sendto(socketfd,&sentbuf,sizeof(sentbuf),,(struct sockaddr *)&client,sizeof(client));
}
}
}
else if(choice == UPLOAD){
int fd1= open(recvbuf.buf,O_RDONLY);
if (fd1 < ){
sentbuf.command = START;
}
else{
sentbuf.command = NO;
}
close(fd1);
sendto(socketfd,&sentbuf,sizeof(sentbuf),,(struct sockaddr *)&client,sizeof(client));
if(sentbuf.command ==START){
int no =;
int fd =open(recvbuf.buf,O_CREAT | O_TRUNC |O_WRONLY,);
if(fd < ){
perror("create file error\n");
exit();
}
bzero(&recvbuf,sizeof(recvbuf));
while((num = recvfrom(socketfd,&recvbuf,sizeof(recvbuf),,(struct sockaddr *)&server,&addrlen)) >){
if(recvbuf.command == CONTENT){
if(no == recvbuf.no){
write(fd,recvbuf.buf,recvbuf.len);
//printf("kkk%s\n",recvbuf.buf );
bzero(&recvbuf,sizeof(recvbuf));
}
else{
perror("The file no is not same.Some message is missed! error occured! \n");
break;
}
}
if(recvbuf.command == END){
close(fd);
printf("transmission is successful!\n");
break;
}
}
}
else if(sentbuf.command == NO){
printf("Not to trans the file\n");
printf("The file is exist!\n");
}
else{
perror("error! wrong choice!\n");
exit();
} }
else if (recvbuf.command == SHUTDOWN){
printf("Now the server is shutdown!\n");
break;
}
} /*----------------------close ----------*/
close(socketfd);
return ;
}
4.makefile文件;
main:udpserver.o udpclient.o
gcc -o udpserver udpserver.o
gcc -o udpclient udpclient.o
udpserver.o:udpserver.c protocol.h
gcc -c udpserver.c
udpclient.o: udpclient.c protocol.h
gcc -c udpclient.c
clean:
rm -rf *.o
代码写的挺烂的,里面有很多重复的代码和功能,完全可以抽取出来做成一个函数的。以后慢慢再改吧。先完成功能,把上机考试过了再说。
【LINUX/UNIX网络编程】之使用SOCKET进行UDP编程的更多相关文章
- 【Socket编程】通过Socket实现UDP编程
通过Socket实现UDP编程 UDP通信: 1.UDP协议(用户数据报协议)是无连接.不可靠.无序的. 2.UDP协议以数据报作为数据传输的载体. 3.使用UDP进行数据传输时,首先需要将要传输的数 ...
- 【Linux/unix网络编程】之使用socket进行TCP编程
实验一 TCP数据发送与接收 [实验目的] 1.熟练掌握套接字函数的使用方法. 2.应用套接字函数完成基本TCP通讯,实现服务器与客户端的信息交互. [实验学时] 4学时 [实验内容] 实现一个服务器 ...
- 【LINUX/UNIX网络编程】之简单多线程服务器(多人群聊系统)
RT,Linux下使用c实现的多线程服务器.这个真是简单的不能再简单的了,有写的不好的地方,还希望大神轻拍.(>﹏<) 本学期Linux.unix网络编程的第四个作业. 先上实验要求: [ ...
- 【LINUX/UNIX网络编程】之使用消息队列,信号量和命名管道实现的多进程服务器(多人群聊系统)
RT,使用消息队列,信号量和命名管道实现的多人群聊系统. 本学期Linux.unix网络编程的第三个作业. 先上实验要求: 实验三 多进程服务器 [实验目的] 1.熟练掌握进程的创建与终止方法: 2 ...
- linux/unix网络编程之 select
转自http://www.cnblogs.com/zhuwbox/p/4221934.html linux 下的 select 知识点 unp 的第六章已经描述的很清楚,我们这里简单的说下 selec ...
- python网络-Socket之udp编程(24)
一.udp简介 udp --- 用户数据报协议,是一个无连接的简单的面向数据报的运输层协议. udp不提供可靠性,它只是把应用程序传给IP层的数据报发送出去,但是并不能保证它们能到达目的地. udp在 ...
- 十、Socket之UDP编程
UDP基础知识 UDP(User Datagram Protocol,用户数据报协议)是一个简单的.面向数据报的无连接协议,提供了快速但不一定可靠的传输服务. UDP与TCP相比主要有以下区别. 1. ...
- [C# 网络编程系列]专题六:UDP编程
转自:http://www.cnblogs.com/zhili/archive/2012/09/01/2659167.html 引用: 前一个专题简单介绍了TCP编程的一些知识,UDP与TCP地位相当 ...
- 【Socket编程】通过Socket实现TCP编程
通过Socket实现TCP编程 Socket通信 : 1.TCP协议是面向对象连接.可靠的.有序的,以字节流的方式发送数据. 2.基于TCP协议实现网络通信的类: 客户端----Socket类 服务器 ...
- [C# 网络编程系列]专题七:UDP编程补充——UDP广播程序的实现
转自:http://www.cnblogs.com/zhili/archive/2012/09/03/2666974.html 上次因为时间的关系,所以把上一个专题遗留下的一个问题在本专题中和大家分享 ...
随机推荐
- Unity3d iOS基本优化和高级优化
原地址:http://www.cocoachina.com/bbs/read.php?tid=70395&page=1 分享看见的2篇好文.简单翻译了一下并且放出原文 http://www.c ...
- crontab添加定时任务
(这些文章都是从我的个人主页上粘贴过来的,大家也可以访问我的主页 www.iwangzheng.com) crontab是LINUX系统下的定时任务触发器,常用的方法如下: crontab -l ...
- 解决eclipse+MAVEN提示One or more constraints have not been satisfied.的问题
应用版本:eclipse luna4.4.1 JDK:1.8 Maven:3.2.5 问题现象: 1.编译工程后总该是显示下面两个错误: One or more constraints have no ...
- 1.2 中国象棋将帅问题进一步讨论与扩展:如何用1个变量实现N重循环?[chinese chess]
[题目] 假设在中国象棋中只剩下将帅两个棋子,国人都知道基本规则:将帅不能出九宫格,只能上下左右移动,不能斜向移动,同时将帅不能照面.问在这样条件下,所有可能将帅位置.要求在代码中只能使用一个字节存储 ...
- 更改Apache默认网站根目录
Apache服务器网站根目录配置是个比较基本的操作,之前经常用,现在记一下笔记 打开Apache的配置文件,一般在Apache安装目录下的conf/httpd.conf配置文件中修改, 找到 Docu ...
- 用php实现遍历目录
用php实现的遍历目录,只遍历第一层,如果制作在线文件管理器的话很管用,不同目录只加一个超链接就行了,然后给方法传递参数就行了,遍历目录的类如下: class Ergodic{ public func ...
- BM算法 Boyer-Moore高质量实现代码详解与算法详解
Boyer-Moore高质量实现代码详解与算法详解 鉴于我见到对算法本身分析非常透彻的文章以及实现的非常精巧的文章,所以就转载了,本文的贡献在于将两者结合起来,方便大家了解代码实现! 算法详解转自:h ...
- jsp之间传参中文乱码问题
jsp页面之间传参,传中文会出现乱码问题. 如下: $('.yzjjfa_row').eq(0).append('<a class="yzjjfa_contItem jjfa_acti ...
- javascript十六进制数字和ASCII字符之间转换
var hex="0x29";//十六进制 var charValue = String.fromCharCode(hex);//生成Unicode字符 var charCode ...
- 微信api退款操作
状况:证书加载进去,本地调试退款成功,然而发不到iis上却是不成功. 分析:定然是iis配置问题. 问题一:证书加载不进去,出现“内部错误” 解决:在iis中找到对应的应用连接池,右键高级设置,找到“ ...