一、环境配置
密码是: 111111
输入
apt install gcc
然后依次输入
二、一些常用命令
三、实践部分
day02
输入如下图
建议如下图
下载图片后命名为1.jpg,并将图片拖入当前文件,然后在mycp.c中输入如下
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
int main(int argc ,char* argv[],char* envp[])
{
int fd = open("1.jpg",O_RDONLY);
if (fd == -1)
{
printf("open failed\n");
exit(1);
}
int filesize = lseek(fd,0,SEEK_END);
printf("filesize = %d\n",filesize);
lseek(fd,0,SEEK_SET);
char buff[128] = {0};
int n = read(fd,buff,128);
printf("n=%d\n",n);
close(fd);
exit(0);
}
day03
输入及结果的图片
输入代码
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <pthread.h>
void* fun(void * arg)
{
for(int i = 0; i< 10; i++)
{
printf("fun run\n");
sleep(1);
}
pthread_exit("fun over");
}
int main()
{
pthread_t id;//int a;float f;
pthread_create(&id,NULL,fun,NULL);
for(int i = 0; i< 5; i++)
{
printf("main run\n");
sleep(1);
}
char * s = NULL;
pthread_join(id,(void**)&s);
printf("s=%s\n",s);
exit(0);
}
day04
建立服务端和客户端
在两个窗口中分别运行
./ser
./cli
创建服务端
vi ser.c
输入代码
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
//服务器端的代码
int main()
{
int sockfd = socket(AF_INET,SOCK_STREAM,0);//创建套接字
if (sockfd == -1)
{
exit(1);
}
struct sockaddr_in saddr,caddr;//表示套接字的地址
memset(&saddr,0,sizeof(saddr));
saddr.sin_family = AF_INET;
saddr.sin_port = htons(6000);
saddr.sin_addr.s_addr = inet_addr("127.0.0.1");
int res = bind(sockfd,(struct sockaddr*)&saddr,sizeof(saddr));
if(res == -1)
{
printf("bind err\n");
exit(1);
}
res = listen(sockfd,5);
if (res == -1)
{
exit(1);
}
while(1)
{
int len = sizeof(caddr);
int c = accept(sockfd,(struct sockaddr*)&caddr,&len);//接受连接(可能堵塞)
if(c < 0)
{
continue;
}
printf("accept c=%d\n,ip=%s,port=%d\n",c,inet_ntoa(caddr.sin_addr),ntohs(caddr.sin_port));
while(1)
{
char buff[128] = {0};
int num = recv(c,buff,127,0);
if(num<=0)
{
break;
}
printf("buff=%s\n",buff);
send(c,"ok",2,0);
}
close(c);
printf("client close\n");
}
}
客户端
vi cli.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
//客户端编译
int main()
{
int sockfd = socket(AF_INET,SOCK_STREAM,0);
if (sockfd == -1)
{
exit(1);
}
struct sockaddr_in saddr;
memset(&saddr,0,sizeof(saddr));
saddr.sin_family = AF_INET;
saddr.sin_port = htons(6000);
saddr.sin_addr.s_addr = inet_addr("127.0.0.1");
int res = connect(sockfd,(struct sockaddr*)&saddr,sizeof(saddr));
if (res == -1)
{
printf(":connect errr\n");
exit(1);
}
while( 1 )
{
printf("input:\n");
char buff[128] = {0};
fgets(buff,128,stdin);
if( strncmp(buff,"end",3) == 0)
{
break;
}
send(sockfd,buff,strlen(buff),0);
memset(buff,0,128);
recv(sockfd,buff,127,0);
printf("buff=%s\n",buff);
}
close(sockfd);
exit(0);
}
day05
修改 ser.c
运行代码
gcc -o ser ser.c -lpthread
运行结果如下
修改后ser.c的代码:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <pthread.h>
void* work_thread(void *arg)
{
int c = (int)arg;
while( 1 )
{
char buff[128] = {0};
int num = recv(c,buff,127,0);
if ( num <= 0 )
{
break;
}
printf("cli c=%d,buff=%s\n",c,buff);
send(c,"ok",2,0);
}
close(c);
printf("client close\n");
}
//ser
int main()
{
int sockfd = socket(AF_INET,SOCK_STREAM,0);//创建套接字
if (sockfd == -1)
{
exit(1);
}
struct sockaddr_in saddr,caddr;//表示套接字的地址
memset(&saddr,0,sizeof(saddr));
saddr.sin_family = AF_INET;
saddr.sin_port = htons(6000);
saddr.sin_addr.s_addr = inet_addr("127.0.0.1");
int res = bind(sockfd,(struct sockaddr*)&saddr,sizeof(saddr));
if(res == -1)
{
printf("bind err\n");
exit(1);
}
res = listen(sockfd,5);
if (res == -1)
{
exit(1);
}
while( 1 )
{
int len = sizeof(caddr);
int c = accept(sockfd,(struct sockaddr*)&caddr,&len);//接受连接(可能堵塞)
if(c < 0)
{
continue;
}
printf("accept c=%d,ip=%s,port=%d\n",c,inet_ntoa(caddr.sin_addr),ntohs(caddr.sin_port));
pthread_t id;
pthread_create(&id,NULL,work_thread,(void*)c);
}
}
创建main.c文件,运行结果如图
代码如下
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
char buff[128] = {"a-b-c-d-e-f-g-h"};
char * ptr = NULL;
char * s = strtok_r(buff,"-",&ptr);
while(s != NULL)
{
printf("s=%s\n",s);
s = strtok_r(NULL,"-",&ptr);
}
exit(0);
}
创建myhttp_code目录,在该目录下创建 myhttp.c 文件。
运行myhttp.c文件
其中myhttp.c文件代码如下
#include<stdio.h>
#include<string.h>
#include<unistd.h>
#include<stdlib.h>
#include<sys/socket.h>
#include<arpa/inet.h>
#include<netinet/in.h>
#include<pthread.h>
#include<fcntl.h>
#include<signal.h>
#define PORT 80
#define IPS "127.0.0.1"
#define LIS_MAX 5
#define BUFF_SIZE 4096
int socket_init();
int accept_client(int sockfd);
void *thread_run(void* arg);
char* get_filename(char buff[]);
int main()
{
int sockfd = socket_init();
if(sockfd == -1)
{
exit(1);
}
while(1)
{
int c = accept_client(sockfd);
if( c < 0 )
{
continue;
}
pthread_t id;
pthread_create(&id, NULL, thread_run, (void*)c);
}
}
int accept_client(int sockfd)
{
struct sockaddr_in caddr;
int len = sizeof(caddr);
int c = accept(sockfd, (struct sockaddr*)&caddr, &len);
return c;
}
char* get_filename(char buff[])
{
if(buff == NULL)
{
return NULL;
}
char* ptr = NULL;
char* s = strtok_r(buff, " ", &ptr);
if(s == NULL)
{
return NULL;
}
printf("请求方法:%s\n", s);
s = strtok_r(NULL, " ", &ptr);
return s;
}
void *thread_run(void* arg)
{
int c = (int)arg;
while(1)
{
char buff[BUFF_SIZE] = {0};
int n = recv(c, buff, BUFF_SIZE-1, 0);
if(n <= 0)
{
break;
}
printf("recv:\n%s\n", buff);
char *filename = get_filename(buff);
if(filename == NULL)
{
send(c, "404", 3, 0);
break;
}
printf("浏览器请求的资源文件为:%s\n", filename);
char http_head[256]= {"HTTP/1.1 200 OK\r\n"};
strcat(http_head, "Server: myhttp\r\n");
strcat(http_head, "Content-Length: 2\r\n");
strcat(http_head, "\r\n");
strcat(http_head, "OK");
send(c, http_head, strlen(http_head), 0);
printf("send:\n%s\n", http_head);
}
close(c);
printf("client close\n");
}
int socket_init()
{
int sockfd = socket(AF_INET, SOCK_STREAM, 0);
if(sockfd == -1)
{
return -1;
}
struct sockaddr_in saddr;
memset(&saddr, 0, sizeof(saddr));
saddr.sin_family = AF_INET;
saddr.sin_port = htons(PORT);
saddr.sin_addr.s_addr = inet_addr(IPS);
int res = bind(sockfd,(struct sockaddr*)&saddr,sizeof(saddr));
if(res == -1)
{
printf("bind err\n");
return -1;
}
res = listen(sockfd, LIS_MAX);
if(res == -1)
{
printf("listen err\n");
return -1;
}
return sockfd;
}
day6
再次修改myhttp.c
在myhttp_code目录下创建index.html和test.html文件
其中index.html文件中需要1.jpg文件,需要在虚拟机网络中下载图片,并命名为1.jpg,保存在myhttp_code目录下
运行myhttp.c文件,
gcc -o myhttp myhttp.c -lpthread
运行成功后进入root模式
sudo su
然后输入
./myhttp
将文件运行起来
点击虚拟机文件夹,点击index.html,可以看见一个网页。
或者在虚拟机网页中输入127.0.0.1/index.html,也可以打开网页。
myhttp.c 代码如下:
#include<stdio.h>
#include<string.h>
#include<unistd.h>
#include<stdlib.h>
#include<sys/socket.h>
#include<arpa/inet.h>
#include<netinet/in.h>
#include<pthread.h>
#include<fcntl.h>
#define PORT 80
#define IPS "127.0.0.1"
#define LIS_MAX 5
#define BUFF_SIZE 4096
#define PATH "/home/stu/myhttp_code"
int socket_init();
int accept_client(int sockfd);
void *thread_run(void* arg);
char* get_filename(char buff[]);
int open_file(char *path, int *pfilesize);
int main()
{
int sockfd = socket_init();
if(sockfd == -1)
{
exit(1);
}
while(1)
{
int c = accept_client(sockfd);
if( c < 0 )
{
continue;
}
pthread_t id;
pthread_create(&id, NULL, thread_run, (void*)c);
}
}
int accept_client(int sockfd)
{
struct sockaddr_in caddr;
int len = sizeof(caddr);
int c = accept(sockfd, (struct sockaddr*)&caddr, &len);
return c;
}
char* get_filename(char buff[])
{
if(buff == NULL)
{
return NULL;
}
char* ptr = NULL;
char* s = strtok_r(buff, " ", &ptr);
if(s == NULL)
{
return NULL;
}
printf("请求方法:%s\n", s);
s = strtok_r(NULL, " ", &ptr);
return s;
}
void *thread_run(void* arg)
{
int c = (int)arg;
while(1)
{
char buff[BUFF_SIZE] = {0};
int n = recv(c, buff, BUFF_SIZE-1, 0);
if(n <= 0)
{
break;
}
printf("recv:\n%s\n", buff);
char *filename = get_filename(buff);
if(filename == NULL)
{
send(c, "404", 3, 0);
break;
}
printf("浏览器请求的资源文件为:%s\n", filename);
char path[256] = { PATH };
if(strcmp(filename, "/") == 0)
{
strcat(path, "/index.html");
}
else
{
strcat(path, filename);
}
int filesize = 0;
int fd = open_file(path, &filesize);
if(fd == -1)
{
send(c, "404", 3, 0);
break;
}
char http_head[256]= {"HTTP/1.1 200 OK\r\n"};
strcat(http_head, "Server: myhttp\r\n");
//strcat(http_head, "Content-Length: 2\r\n");
sprintf(http_head + strlen(http_head), "Content-Length: %d\r\n", filesize);
strcat(http_head, "\r\n");
send(c, http_head, strlen(http_head), 0);
printf("send:\n%s\n", http_head);
char data[1024] = {0};
int num = 0;
while((num = read(fd, data, 1024)) > 0)
{
send(c, data, num, 0);
}
close(fd);
}
close(c);
printf("client close\n");
}
int open_file(char *path, int *pfilesize)
{
if(path == NULL || pfilesize == NULL)
{
return -1;
}
int fd = open(path, O_RDONLY);
if(fd == -1)
{
*pfilesize = 0;
return -1;
}
*pfilesize = lseek(fd,0,SEEK_END);
lseek(fd,0,SEEK_SET);
return fd;
}
int socket_init()
{
int sockfd = socket(AF_INET, SOCK_STREAM, 0);
if(sockfd == -1)
{
return -1;
}
struct sockaddr_in saddr;//s:myself
memset(&saddr, 0, sizeof(saddr));
saddr.sin_family = AF_INET;
saddr.sin_port = htons(PORT);
saddr.sin_addr.s_addr = inet_addr(IPS);
int res = bind(sockfd,(struct sockaddr*)&saddr,sizeof(saddr));
if(res == -1)
{
printf("bind 80 err\n");
return -1;
}
res = listen(sockfd, LIS_MAX);
if(res == -1)
{
printf("listen err\n");
return -1;
}
return sockfd;
}
index.html
test.html