UDP协议ICMP协议的理解及UDP套接口和原始套接口
1.使用UDP编程服务器端和客户端程序
(1)要求:客户端将文件A1和A2,内容交替发送给服务器;服务器大小写转换后交替传给客户端;客户端接受后存为B1和B2。
文件头:
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <time.h>
#include <signal.h>
#include <stdio.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <ctype.h> /*for toupper*/
#define SERVPORT 3333
#define NDG 2000
#define DGLEN 1400
主要代码:
客户端:(udpcli.c)
void dg_cli(FILE *fp,FILE *fp1,int sockfd,const struct sockaddr* pservaddr,socklen_t servlen)//缺乏流量控制
{
int n,i=0,flag,empty1=0,empty2=0;
char sendline[1024],recvline[1025];
FILE *fp2,*fp3;
if ((fp2 = fopen("b1.txt","r+")) == NULL) {
perror("Open file failed\n");
exit(0);
}
if ((fp3 = fopen("b2.txt","r+")) == NULL) {
perror("Open file failed\n");
exit(0);
}
for(;;){
flag=i%2;
if(flag == 0)
{
if(fgets(sendline,10,fp)!=NULL){
printf("send file A1: %s\n",sendline);
sendto(sockfd,sendline,strlen(sendline),0,pservaddr,servlen);
n=recvfrom(sockfd,recvline,1024,0,NULL,NULL);
recvline[n]='\0';
printf("received 1(saved in B1):");
fputs(recvline,stdout); //输出到屏幕
printf("\n");
fwrite(recvline,sizeof(char),strlen(recvline),fp2);//写到B1文件夹
}
else empty1=1;
i++;
}
else if(flag == 1)
{
if(fgets(sendline,10,fp1)!=NULL){
printf("send file A2: %s\n",sendline);
sendto(sockfd,sendline,strlen(sendline),0,pservaddr,servlen);
n=recvfrom(sockfd,recvline,1024,0,NULL,NULL);
recvline[n]='\0';
printf("received 2(saved in B2):");
fputs(recvline,stdout);
printf("\n");
fwrite(recvline,sizeof(char),strlen(recvline),fp3);//写到B2文件夹
}
else empty2=1;
i++;
}
if(empty1==1&&empty2==1) {
printf("end of send!\n");
break;
}
}
fclose(fp2);
fclose(fp3);
}
int main(int argc,char*argv[]){
int sockfd;
struct sockaddr_in servaddr;
char buff[1024];
int n,len;
FILE *fp,*fp1;
if ((fp = fopen("a1.txt","r")) == NULL) {
perror("Open file failed\n");
exit(0);
}
if ((fp1 = fopen("a2.txt","r")) == NULL) {
perror("Open file failed\n");
exit(0);
}
bzero(&servaddr,sizeof(servaddr));
servaddr.sin_family=AF_INET;
inet_aton("127.0.0.1",&servaddr.sin_addr);
servaddr.sin_port=htons(SERVPORT);
sockfd=socket(AF_INET,SOCK_DGRAM,0);
if(sockfd<0){
fprintf(stderr,"Socket error");
exit(1);
}
dg_cli(fp,fp1,sockfd,(struct sockaddr *)&servaddr,sizeof(servaddr));
fclose(fp);
fclose(fp1);
exit(0);
}
服务器端:(udpser.c)
static int count;
static void recvfrom_int(int);
void udps_respon(int sockfd,struct sockaddr* pcliaddr,socklen_t clilen){
int n;
char msg[1024];
socklen_t len;
int j=1,i;
for(;;){
len=clilen;
n=recvfrom(sockfd,msg,1024,0,pcliaddr,&len);
/* 响应客户机请求 */
msg[n]='\0';
printf("received message %d:%s \n",j,msg);
for (i = 0; i < n; i++){ //大小写转换
if(msg[i]>='A'&&msg[i]<='Z')
msg[i]+=32;
else if(msg[i]>='a'&&msg[i]<='z')
msg[i]-=32;
}
printf("send message %d:%s \n",j,msg);
sendto(sockfd,msg,n,0,pcliaddr,len);
j++;
}
}
int main(int argc,char*argv[]){
int sockfd;
struct sockaddr_in servaddr,cliaddr;
/* 创建一个UDP数据报类型的套接字 */
sockfd=socket(AF_INET,SOCK_DGRAM,0);
if(sockfd<0){
fprintf(stderr,"Socket error");
exit(1);
}
bzero(&servaddr,sizeof(servaddr));
servaddr.sin_family=AF_INET;
servaddr.sin_addr.s_addr=htonl(INADDR_ANY);
servaddr.sin_port=htons(SERVPORT);
/* 服务器为套接字绑定一个端口号 */
if(bind(sockfd,(struct sockaddr*)&servaddr,sizeof(servaddr))<0){
fprintf(stderr,"Bind error");
exit(1);
}
/* 调用通信函数与客户端进行通信 */
udps_respon(sockfd,(struct sockaddr *)&cliaddr,sizeof(cliaddr));
close(sockfd); /* 关闭套接字 */
}
a1.txt内容:
a2.txt内容:
运行结果:
客户端: