分为请求报文和响应报文 , ASCII编码的字段组成
HTTP/1.1 301 Moved{永久转移}
【HTTP协议】: :port//.html {新的URL}
与间传递的状态信息
HTML
超文本标记语言
好诗 一级标题春江花月夜春江潮水连海平 , 海上明月共潮生 。
滟滟随波千万里 , 何处春江无月明!
江流宛转绕芳甸 , 月照花林皆似霰;
空里流霜不觉飞 , 汀上白沙看不见 。
江天一色无纤尘 , 皎皎空中孤月轮 。
江畔何人初见月?江月何年初照人?
人生代代无穷已 , 江月年年望相似 。
My UNIX do not have Chiness charactor set
使用ASCII编码 , 浏览器直接打开查看效果
HTML允许在网页中插入图像(内含图像 image) , 其中gif格式压缩后体积最小
远程连接:终点在其他网站
本地连接:终点在本计算机
静态文档( )
工人写完后不再改变 , 简单但不灵活
动态文档( )
浏览器访问时程序动态创建
通用网关接口(CGI ,
是一种定义动态文档的创建 , 数据输入(给应用程序) 和 输出的标准
CGI程序 是 脚本程序( )
活动文档( )
TCP/IP
了解套接字编程 , 主要
变量有:
(_fd)
函数有:
端的()、send()、recv()
端()、()
#include #include #include #include #include #include #include //-------------------//V1.0 接收请求 , 显示报文//-------------------using namespace std;int main(void){int listener=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);if(listener==(int)(~0)){ cout<<"Listenner Initiate Failure!"<
在Unix系统下运行以上源文件编写的 , 再使用其他主机上的浏览器通过URL访问任意上的资源 , 都会打印HTTP请求的内容
可以手写响应报文:
char sendData[512]={0};strcpy(sendData,"HTTP/1.1 202 OK!\r\ncontent-type: text/html; charset=UTF-8\r\n\r\nTryTitle-C1");send(Client_id,&sendData,512,0);
再使用其他主机上的浏览器通过URL访问任意上的资源 , 将返回响应报文
在浏览器中可以看到响应报文实体(html文档)在浏览器中显示的效果
按下F12使用控制台 , 刷新后重新访问URL , 可查看响应报文的标头
文件存取
首先提取请求中的文件名 , 然后使用中的类open(请求的file) , open()函数搜索可执行文件所在的目录下是否存在目标文件 , 成功打开后读取内容 , 并与HTTP的开始行、首部行 , 一并返回
//-----------------------------------//V2.0 接受请求 , 分析URL , 响应传输html文档//-----------------------------------#include #include #include #include #include #include #include #include #include using namespace std;int main(void){int listener=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);if(listener==(int)(~0)){ cout<<"Listenner Initiate Failure!"<>tmp)content=content+tmp;cout<
进程与线程 线程间通信
() , recv()会阻塞 , 需要特别小心
如多线程项目中 , 收到退出信号后 , 阻塞态的主线程在收到(不可能到来的)下一个信号前 , 无法响应退出命令
可以将他们设置为非阻塞
并发回显测试
/* -----------------------------------------------------------------Server.V3.0.CentOS 多线程接受 , 回显 , 主线程main中accept()会阻塞 , CloseServer需发送两次以上-------------------------------------------------------------------*/#include #include #include #include #include #include #include #include #include #include #include #include #include using namespace std;#define ERROR ((int)(~0))#define MAX_THREAD_NUM 4#define MAX_REQ_NUM 512bool exit_flag=false;int thread_no[MAX_THREAD_NUM];pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;vector > Client_id(MAX_THREAD_NUM);//线程请求队列void *pthread_start_fcn(void *);//线程启动函数int find_shortest_deque(vector >&); //最短队列查找bool empty_check(vector >&);//空队列检测bool full_check(vector >&);//满队列检测int main(void){//监听套接字int listener=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);if(listener==ERROR){ cout<<"Listenner Initiate Failure!"< &Client_id){int shortest = 0;int min_req = MAX_REQ_NUM;for(int i=0;i > &Client_id){bool empty = true;for(int i=0;i0){empty = false;break;}return empty;}bool full_check(vector > &Client_id){bool full = true;for(int i=0;i
/*Client.3.0.windows. 并发回显测试Client端须在Visual Studio的项目属性-->链接器-->命令行中输入"ws2_32.lib" */#include#include#include#pragma warning(disable : 4996)#define REQ_NUM 50//并发请求数量char ip_addr[] = { "192.168.31.246" };using namespace std;int main(void){WORD socket_ver = MAKEWORD(2, 2);WSADATA data;if (WSAStartup(socket_ver, &data) != 0){cout << "WSAStartup failed!" << endl;return 0;}while (true){string input;cin >> input;if (!strcmp(input.c_str(), "CloseClient"))break;for (int i = 0; i < REQ_NUM; i++){SOCKET client = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);if (client == INVALID_SOCKET){cout << "Socket Init Failure!" << endl;continue;}sockaddr_in server;server.sin_family = AF_INET;server.sin_port = htons(8080);server.sin_addr.S_un.S_addr = inet_addr(ip_addr);if (connect(client, (const sockaddr*)&server, sizeof(server)) == SOCKET_ERROR){cout << "Connect Failure!" << endl;break;}char sendmsg[255] = { '\0' };char no[10] = { '\0' };sprintf(no, "%d", i);strcat(sendmsg, "REQ_No.");strcat(sendmsg, no);strcat(sendmsg, " : ");strcat(sendmsg, input.c_str());send(client, sendmsg, 255, 0);char recvmsg[255] = {};recv(client, recvmsg, 255, 0);cout << "Server:" << endl << recvmsg << endl;closesocket(client);}}WSACleanup();return 0;}