网络骇客入门之TCP并发网页服务器

TCP并发服务器本来准备写在网络骇客入门之TCP编程后面的,但是因为代码有点长,所以就单独写了一篇

注意:

因为浏览器发送的数据比较多,所以作为本服务器的接受缓冲区recv_buf要大点,至少512字节,建议1024字节

如果接收不全的话,无论如何都不能将网页传给浏览器,这个bug卡了我一晚上,所以记得特别清楚。

创建线程时传给线程的参数注意写连接套接字的值,先转换为(void*)类型,

pthread_create(&pth,NULL,msg_echo,(void *)connfd);

再在线程里转回(int)型

int connfd = (int)arg;

不能写地址,防止如果同时有多个请求时connfd的值变得太快,在子线程取地址取出来之前值就变了

1.头文件

#include <stdio.h>

#include <unistd.h>

#include <string.h>

#include <stdlib.h>

#include <arpa/inet.h>

#include <sys/socket.h>

#include <netinet/in.h>

#include <pthread.h>

#include <fcntl.h>

//子线程处理浏览器的网页请求

void *msg_echo(void *arg)

{

int connfd = (int)arg;

int ret_read=0;

int ret_recv=0;

char recv_buf[1024]="";

char read_buf[1024]="";

char send_buf[1024]="";

int fd;

char filename[50] = "html/";

//请求成功返回

char head[]="HTTP/1.1 200 OK\r\n" \

"Content-Type: text/html\r\n" \

"\r\n";

//请求失败返回

char err[]= "HTTP/1.1 404 Not Found\r\n" \

"Content-Type: text/html\r\n" \

"\r\n" \

"<HTML><BODY>File not found</BODY></HTML>";

printf("connfd=%d\n",connfd);

//接收请求数据

ret_recv = recv(connfd,recv_buf,sizeof(recv_buf),0);

printf("ret_recv:%d\n",ret_recv);

//读取网页文件名

sscanf(recv_buf+4, "%[^ ]", (filename + 5));

printf("filename:%s\n",filename);

//打开网页文件

fd = open(filename, O_RDONLY);

if(fd < 0)

{

perror("open");

send(connfd, err, strlen(err), 0);

close(connfd);

return NULL;

}

//将网页文件发给浏览器

send(connfd,head,strlen(head),0);

while((ret_read = read(fd,read_buf,sizeof(read_buf)))>0)

{

// printf("%s\n",read_buf);

send(connfd,read_buf,ret_read,0);

}

close(connfd);

close(fd);

}

2.main函数

int main(int argc, char *argv[])

{

unsigned int port=8000;//设置端口

if(argc > 1)//可指定端口

{

port = atoi(argv[1]);

}

int sockfd;

struct sockaddr_in my_addr;

// 结构体

memset(&my_addr,0,sizeof(my_addr));

my_addr.sin_family = AF_INET;

my_addr.sin_port = htons(port);

my_addr.sin_addr.s_addr = htonl(INADDR_ANY);

// 套接字

sockfd = socket(AF_INET, SOCK_STREAM, 0);

if(sockfd < 0)

{

perror("socket");

exit(-1);

}

//绑定端口

int err = bind(sockfd,(struct sockaddr*)&my_addr,sizeof(my_addr));

if(err != 0)

{

perror("bind");

close(sockfd);

exit(-1);

}

//监听端口

err = listen(sockfd,10);

if(err != 0)

{

perror("listen");

close(sockfd);

exit(-1);

}

printf("listen at %d\n",port);

//多线程处理连接请求

while(1)

{

int connfd;//连接套接字

struct sockaddr_in client_addr;

char cli_ip[INET_ADDRSTRLEN]="";

socklen_t cliaddr_len = sizeof(client_addr);

//接受请求

connfd = accept(sockfd,(struct sockaddr *)&client_addr,&cliaddr_len);

if(connfd < 0)

{

perror("accept");

}

//输出连接者信息

inet_ntop(AF_INET,&client_addr.sin_addr,cli_ip,INET_ADDRSTRLEN);

printf("accepted--ip:%s  port:%d\n",cli_ip,ntohs(client_addr.sin_port));

//创建线程

pthread_t pth;

pthread_create(&pth,NULL,msg_echo,(void *)connfd);

pthread_detach(pth);

}

close(sockfd);

return 0;

}

原文地址:http://blog.51cto.com/13603157/2095502

时间: 2024-08-25 13:38:49

网络骇客入门之TCP并发网页服务器的相关文章

网络骇客入门之UDP编程

本文列出了在LINUX系统下使用C语言进行UDP收发操作的常用函数和用法 注意: 创建套接字时,系统会分配一个临时端口,默认主动发起服务请求,作为服务器时可修改为被动 发送数据时,不需要用bind绑定端口(当然绑定也可以) 接收数据时,如果不想知道发送者的信息(如:IP地址,端口等),可以不创建发送者结构体,然后recvfrom的后两个参数写NULL 因为网络上的字节序是大端格式(低地址存高字节),所以在发送数据和显示接收的数据时要用htonl/htons和ntohl/ntohs转换(即host

网络骇客初级之原始套接字(SOCK_RAW)

本文用实际程序完成了MAC数据包分析,网络数据分析,MAC地址扫描器和飞秋欺骗 在这里我把原来的入门改成了初级,因为对于原始套接字的操作确实在普通的TCP,UDP之上 TCP和UDP确实涵盖了普通的网络应用程序,但请注意"普通"二字,要成为一名骇客的你,可不能仅仅满足于写一些普通的网络小程序,而要直接对所有数据包进行分析,还要能够发送自己组装的数据包,踏入高级网络编程的领域,编写一些奇特的网络程序(嘿嘿!). 注意所有程序都是在LINUX系统下实现的,当然在windows下不是不行,只

【Java】Java网络编程菜鸟进阶:TCP和套接字入门

Java网络编程菜鸟进阶:TCP和套接字入门 JDK 提供了对 TCP(Transmission Control Protocol,传输控制协议)和 UDP(User Datagram Protocol,用户数据报协议)这两个数据传输协议的支持.本文开始探讨 TCP. TCP 基础知识 在“服务器-客户端”这种架构中,服务器和客户端各自维护一个端点,两个端点需要通过网络进行数据交换.TCP 为这种需求提供了一种可靠的流式连接,流式的意思是传出和收到的数据都是连续的字节,没有对数据量进行大小限制.

Linux网络编程——tcp并发服务器(多进程)

一.tcp并发服务器概述 一个好的服务器,一般都是并发服务器(同一时刻可以响应多个客户端的请求).并发服务器设计技术一般有:多进程服务器.多线程服务器.I/O复用服务器等. 二.多进程并发服务器 在 Linux 环境下多进程的应用很多,其中最主要的就是网络/客户服务器.多进程服务器是当客户有请求时,服务器用一个子进程来处理客户请求.父进程继续等待其它客户的请求.这种方法的优点是当客户有请求时,服务器能及时处理客户,特别是在客户服务器交互系统中.对于一个 TCP 服务器,客户与服务器的连接可能并不

Linux网络编程——tcp并发服务器(多线程)

tcp多线程并发服务器 多线程服务器是对多进程服务器的改进,由于多进程服务器在创建进程时要消耗较大的系统资源,所以用线程来取代进程,这样服务处理程序可以较快的创建.据统计,创建线程与创建进程要快 10100 倍,所以又把线程称为"轻量级"进程.线程与进程不同的是:一个进程内的所有线程共享相同的全局内存.全局变量等信息,这种机制又带来了同步问题. tcp多线程并发服务器框架: 我们在使用多线程并发服务器时,直接使用以上框架,我们仅仅修改client_fun()里面的内容. 代码示例: #

TCP并发服务器,每个客户一个子进程

在阅读完<unix 网络编程:卷一>之后,感觉作者真是unix下编程的大师级的人物.而对于我个人而言,每次阅读完一本技术书籍之后,一定还是得自己重新再写一遍程序(换点内容),复习书本中的内容(大致结构,或者说思想,相同),否则,你很难做到真的理解并掌握的地步. Okay,今天我带来的是服务器模型中的第一种,也是最基本最常用的一种模型–TCP并发服务器,每个客户一个子进程. 先简单介绍一下:TCP并发服务器,每个客户一个子进程,也就是说并发服务器调用fork派生一个子进程来处理每个子进程,使得服

TCP并发server,每个客户一个子进程

今天笔者带来的是server型号第一,这是最经常使用的模型的最基本的一个–TCP并发server,每个客户一个子进程. 首先简单介绍:TCP并发server,每个客户一个子进程,并发server调用fork派生一个子进程来处理每一个子进程,使得server能够同一时候为多个客户服务,每一个进程一个客户. 客户数目的唯一限制是操作系统对以其名义执行server的用户ID能够同一时候拥有多少子进程的限制. 详细到我们的需求,我们的client发送某个指令,服务端接收.假设符合服务端的要求.就将当时的

为什么一个Http Header中的空格会被骇客利用 - HTTP request smuggling

前言 507383170 前阵子在Netty的issue里有人提了一个问题 http request smuggling, cause by obfuscating TE header ,描述了一个Netty的http解码器一直以来都存在的问题:没有正确地分割http header field名称,可能导致被骇客利用. 引起问题的那段code很简单,它的作用是从一个字符串中分割出header field-name: for (nameEnd = nameStart; nameEnd < leng

H3C-H3CNE 华三网络工程师从入门到精通

课程目标:本课程详细讲解大中型企业网络.数据包结构.OSI模型.TCP/IP模型.IP编址.IP子网划分.TCP.UDP.ICMP.H3C命令行简介.STP.MSTP.VLAN.Trunk.NAT.静态路由.RIP.OSPF.BGP.Telnet.SSH.DHCP.ACL.PPP.IRF.链路聚合.VRRP.BFD 等. 适合人群:本课程适合初级网络系统集成工程师.在校大学生.有网络基础的运维工程师.技术支持等人学习. 课程介绍: 本课程涉及计算机网络基础知识.企业网常用技术介绍.H3C路由器和