Chinaunix首页 | 论坛 | 博客
  • 博客访问: 25977
  • 博文数量: 16
  • 博客积分: 770
  • 博客等级: 军士长
  • 技术积分: 195
  • 用 户 组: 普通用户
  • 注册时间: 2009-03-02 10:33
文章分类

全部博文(16)

文章存档

2011年(1)

2009年(15)

我的朋友

分类: LINUX

2009-03-16 17:02:01

这几天学习了TCP和UDP的编程。
 记下程序。
TCP SERVER:1.创建SOCKET ->2.绑定SOCKET->3.侦听SOCKET->如果发现有链接,则可创建子进程去处理。(子进程中注意要CLOSE掉父进程中的SOCKET)。下面是简单的网络SHELL,草稿,未整理,只实现基本功能,因为重点在网络编程。
#include
#include
#include
#include
#include
int read_line(int fd,char *buf,size_t size);
int main(int argc, char **argv)
{
 int socketfd;
 struct sockaddr_in sevaddr;
 int port=8000;
 if(argc==2)
 {
  port = atoi(argv[1]);
 }
 socketfd = socket(AF_INET,SOCK_STREAM,0);
 sevaddr.sin_port = htons(port);
 sevaddr.sin_addr.s_addr = INADDR_ANY;
 sevaddr.sin_family = AF_INET;
 if(bind(socketfd,(struct sockaddr*)&sevaddr,sizeof(struct sockaddr))==-1)
 {
  perror("bind error!\n");
  exit(1);
 }
 if(listen(socketfd,1)==-1)
 {
  perror("listen error!\n");
  exit(1);
 }
 while(1)
 {
  struct sockaddr_in cliaddr;
  char ip[80];
  pid_t pid;
  int confd;
  int length = sizeof(struct sockaddr);
  confd = accept(socketfd, (struct sockaddr*)&cliaddr,&length);
  printf("connect with :%s",(char*)inet_ntop(AF_INET,&cliaddr.sin_addr.s_addr,ip,80));
  
  pid=fork();
  if(!pid)
  { char recvbuf[2048];
   memset(recvbuf,0,2048);
   size_t recvlen;
   while((recvlen=read_line(confd,recvbuf,2048))>0)
   {
    int i=0;
    pid_t pid1;
    char *arg[5]={NULL};
    recvbuf[recvlen-2]='\0';
    arg[0] = strtok(recvbuf," ");
    while(arg[i])
    {
     printf("%s\n",arg[i]);
     i++;
     arg[i] = strtok(NULL," ");
    }
    pid1 = fork();
    if(!pid1)
    {
     dup2(confd,1);
     execvp(arg[0],&arg[0]);
     exit(0);
    }
   }
   exit(0);
   printf("disconnect !\n");
  }
  close(confd);
 }
 close(socketfd);
}
int read_line(int fd,char *buf,size_t size)
{
 int recvlen,offset=0;
 while((recvlen = recv(fd,buf+offset,size-offset,0))>0)
 {
  if((strchr(buf,'\n')!=NULL)||(strchr(buf,'\r')!=NULL))break;
  if(recvlen == (size - offset))
   break;
  offset += recvlen;
 }
 if(recvlen <= 0)
  return recvlen;
 return (offset + recvlen);
}
客户端用TELNET链接该简单服务器。
下面是WEB服务器,基于HTTP1.1。
#include
#include
#include
#include
#include
#include
#include
void str_deal(int fd,char *buf);
int main(int argc, char **argv)
{
 int socketfd;
 struct sockaddr_in sevaddr;
 int port=80;
 socketfd = socket(AF_INET,SOCK_STREAM,0);
 sevaddr.sin_port = htons(port);
 sevaddr.sin_addr.s_addr=INADDR_ANY;
 sevaddr.sin_family = AF_INET;
 if(bind(socketfd,(struct sockaddr*)&sevaddr,sizeof(struct sockaddr))==-1)
 {
  perror("bind!\n");
  exit(1);
 }
 if(listen(socketfd,1)==-1)
 {
  perror("listen!\n");
  exit(1);
 }
 printf("server is running!\n");
 while(1)
 {
  int status;
  struct sockaddr_in cliaddr;
  char buf[500];
  char IP[30];
  int length = sizeof(struct sockaddr);
  pid_t pid;
  int confd=accept(socketfd,(struct sockaddr*)&cliaddr,&length);
  printf("connect %s\n",(char*)inet_ntop(AF_INET,(char*)&(cliaddr.sin_addr.s_addr),IP,30));
  if(length==-1)
  {
   perror("accept error!\n");
   exit(2);
  }
  if(recv(confd,(char*)buf,500,0)==-1)
  {
   perror("recv error!\n");
   exit(2);
  }
  else
  { 
   pid=fork();
   if(!pid)
   {
    close(socketfd);
    printf("%d\n",confd);
    str_deal(confd ,buf);
    exit(0);
   }
 //  wait(&status);
   
  }
  close(confd);
 }
 close(socketfd);
}
void str_deal(int fd, char *buf)
{
 char *buf_after[5]={NULL};
 int fdhtml;
 char a[] = "command error!";
 char b[] = "HTTP/1.1 404 NOTFound! ";
 char d[50] = "/home/LFS-6.2";
 int i = 0;
 if(strncmp(buf,"GET",3)!=0)
 {
  write(fd,a,sizeof(a));
  exit(1);
 }
 buf_after[0]=strtok(buf," ");
 while(buf_after[i])
 {
  i++;
  buf_after[i]=strtok(NULL," ");
  if(i>3)break;
 }
 strcat(d,buf_after[1]);
 printf("%s\n",d);
 if((fdhtml=open(d,O_RDONLY))==-1)
 {
  write(fd,b,sizeof(b));
  exit(1);
 }
 else
 {
  char mybuf[10000];
 
  char c[]="HTTP/1.1 200 OK\r\nContent-Type:text/html\r\n\r\n";
  int length;
  write(fd,c,sizeof(c));
  while((length=read(fdhtml,mybuf,10000))>0)
  {
   printf("read successful!%d\n",length);
     write(fd,mybuf,length);
   memset(mybuf,'\0',10000);
  }
  
 }
}
下面是基于UDP的TFTP的客户端,和服务器端,写得很烂,怕忘记,记下:
#include
#include
#include
#include
#include
#include
#include
#include
#include
int main(int argc,char **argv)
{
 int sd,i=0,length,fd;
 size_t lenaddr=sizeof(struct sockaddr);
 struct sockaddr_in cliaddr,sevaddr;
 char typ[]="octet";
 char buf[516];
 fd_set readfds;
 struct timeval tv;
 if(argc != 5)
 {
  perror("argument error!\n");
  exit(1);
 }
 
 memset(buf,0,516);
 buf[0] =0x00;
 buf[1] =0x01;
 memcpy((char*)(buf+2),argv[3],strlen(argv[3]));
 buf[2+strlen(argv[3])]=0x00;
 memcpy((char*)(buf+3+strlen(argv[3])),typ,sizeof(typ));
 for(i=0;i<516;i++)
  printf("%x",buf[i]);
 
 sevaddr.sin_family = AF_INET;
 sevaddr.sin_port = htons(69);
 sevaddr.sin_addr.s_addr=inet_addr(argv[1]);
 sd = socket(AF_INET,SOCK_DGRAM,0);
 if(sd < 0)
 {
  printf("socket error!\n");
  exit(1);
 }
 
 sendto(sd,buf,sizeof(buf),0,(struct sockaddr*)&sevaddr,sizeof(struct sockaddr));
 for(i=0;i<516;i++)
  printf("%c",buf[i]);
 printf("\nIP:%s\n",inet_ntoa(sevaddr.sin_addr)); 
 
 memset(buf,0,516);
 if((fd=open(argv[4],O_RDWR|O_CREAT,S_IRUSR|S_IWUSR|S_IXUSR))==-1)
 {
  perror("open error!\n");
  exit(1);
 }
 FD_SET(sd,&readfds);
 select(sd+1,&readfds,NULL,NULL,&tv);
 while((length=recvfrom(sd,(char*)buf,516,0,(struct sockaddr*)&sevaddr,&lenaddr))==516)
 {
  printf("%d\n",length);
  for(i=4;i<516;i++)
  printf("%c",buf[i]);
   write(fd,buf+4,512);
   buf[1]=0x04;
   buf[0]=0x00;
   sendto(sd,buf,4,0,(struct sockaddr*)&sevaddr,sizeof(struct sockaddr)); 
   tv.tv_sec = 1;
   tv.tv_usec = 0;
   select(sd+1,&readfds,NULL,NULL,&tv);
   memset(buf,0,516);
 }
 printf("%d\n",length);
 for(i=4;i  printf("%c",buf[i]);
 write(fd,buf+4,length-4);
 buf[1]=0x04;
 buf[0]=0x00;
 sendto(sd,buf,4,0,(struct sockaddr*)&sevaddr,sizeof(struct sockaddr));
 exit(0);
 
}客户端
 
服务器端:只能执行简单功能,功能扩展中。
 
include
#include
#include
#include
#include
#include
#include
int main(void)
{
 int socketfd;
 struct sockaddr_in seraddr;
 socketfd = socket(AF_INET,SOCK_DGRAM,0);
 char buf[100];
 int length = sizeof(struct sockaddr);
 int port=69;
 if(socketfd == -1)
 {
  perror("sock error!\n");
  exit(1);
 }
 seraddr.sin_port = htons(port);
 seraddr.sin_family = AF_INET;
 seraddr.sin_addr.s_addr = INADDR_ANY;
 if(bind(socketfd, (struct sockaddr*)&seraddr, sizeof(struct sockaddr)) == -1)
 {
  perror("bind error!\n");
  exit(1);
 }
 while(1)
 {
  struct sockaddr_in cliaddr;
  if(recvfrom(socketfd,buf,100,0,(struct sockaddr*)&cliaddr,&length)>0)
  {
   pid_t pid;
  //int INET_ADDRSTRLEN=80;
   char cliIP[80];
   pid = fork();
   
  printf("client ip = %s:", inet_ntop(AF_INET, &cliaddr.sin_addr.s_addr, cliIP, 80));
   if(!pid)
   {
    int clifd = socket(AF_INET,SOCK_DGRAM,0);
    close(socketfd);
    if(buf[1]==1)
    {
     char name[30];
     int fd;
     char read1[516];
     int count=1;
     size_t leng;
     int i;
     strcpy(name,buf+2);
     if((fd = open(name,O_RDONLY))==-1)
     {
      perror("not found!\n");
      exit(1);
     }
     memset(read1,0,516);
     read1[1]=3;
     read1[3]=1;
     while((leng=read(fd,read1+4,512))==512)
     {
      for(i=0;i<516;i++)printf("%c",read1[i]);
      sendto(clifd,read1,516,0,(struct sockaddr*)&cliaddr,sizeof(struct sockaddr));
      memset(read1,0,516);
      count++;
      read1[1]=3;
      read1[3]=count;
      while(1)
      {
       recvfrom(clifd,buf,100,0,(struct sockaddr*)&cliaddr,&length);
       if(buf[1]==4)break;
      }
     }
     printf("fdsafdsafasfdsa\n");
      for(i=0;i<516;i++)printf("%c",read1[i]);
      
      sendto(clifd,read1,leng,0,(struct sockaddr*)&cliaddr,sizeof(struct sockaddr));
      exit(0);
    }
   }
   if(pid < 0)
   {
    perror("fork error!\n");
    exit(0);
   }
   memset(buf,0,100);
  }
 }
 exit(0);
}
阅读(733) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~