这几天学习了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);
}