1 #include <stdio.h> 2 #include <sys/types.h> 3 #include <sys/socket.h> 4 #include <netinet/in.h> 5 #include <arpa/inet.h> 6 #include <string.h> 7 #include <unistd.h> 8 #include <stdlib.h> 9 #include <errno.h> 10 #include <fcntl.h> 11 #include <sys/sendfile.h> 12 #include <sys/stat.h> 13 14 15 16 17 270 int main(int argc, char *argv[]) 271 { 272 int server_sockfd;//服务器端套接字 273 int client_sockfd;//客户端套接字 274 int len,pid; 275 struct sockaddr_in my_addr; //服务器网络地址结构体 276 struct sockaddr_in remote_addr; //客户端网络地址结构体 277 int sin_size; 278 char buf[BUFSIZ]; //数据传送的缓冲区 279 memset(&my_addr, 0, sizeof(my_addr)); //数据初始化--清零 280 my_addr.sin_family = AF_INET; //设置为IP通信 281 my_addr.sin_addr.s_addr = INADDR_ANY; //服务器IP地址--允许连接到所有本地地址上 282 my_addr.sin_port = htons(8000); //服务器端口号 283 284 /*创建服务器端套接字--IPv4协议,面向连接通信,TCP协议*/ 285 if((server_sockfd = socket(PF_INET, SOCK_STREAM, 0)) < 0) 286 { 287 perror("socket"); 288 return 1; 289 } 290 291 /*将套接字绑定到服务器的网络地址上*/ 292 if (bind(server_sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr)) < 0) 293 { 294 perror("bind"); 295 return 1; 296 } 297 298 /*监听连接请求--监听队列长度为5*/ 299 listen(server_sockfd, 5); 300 301 sin_size = sizeof(struct sockaddr_in); 302 349 350 while (1) 351 { 352 client_sockfd = accept(server_sockfd, (struct sockaddr *) &remote_addr, &sin_size); 353 // send(client_sockfd, "Welcome to my server\n", 21, 0); 354 if (client_sockfd < 0) 355 error("ERROR on accept"); 356 pid = fork(); 357 if (pid < 0) 358 error("ERROR on fork"); 359 if (pid == 0) 360 { 361 close(server_sockfd); 362 char html[] = "\r\n\ 363 HTTP/1.1 200 OK \r\n \r\n\ 364 \ 365 <html><head></head><body><h1>HTTP Server</h1></body></html>\ 366 "; 367 recv(client_sockfd, buf, BUFSIZ, 0); 368 printf("%s\n", buf); 369 send(client_sockfd, html, strlen(html), 0); 370 // connection(client_sockfd); 371 // html_handle(client_sockfd); 372 close(client_sockfd); 373 exit(0); 374 } 375 else 376 close(client_sockfd); 377 } /* end of while */ 378 close(server_sockfd); 379 return 0; 380 }
上面是我实现的一个 http server 测试了n久 用浏览器访问总是 直接把http 头 显示到页面上了 , 浏览器不能识别的这个头
浏览器访问结果:
之后我用python 又实现了一次,就没有问题。
有哪位大神知道这是怎么回事?
上面的问题已经解决:
把字符串
"HTTP/1.0 200 OK\r\n\r\n<!DOCTYPE html><html><head></head><body><h1>HTTP Server</h1></body></html>"
分两次发送就OK了
如:
1 send_new(client_sockfd,"HTTP/1.0 200 OK\r\n\r\n"); 2 3 send_new(client_sockfd,"<!DOCTYPE html><html><head></head><body><h1>HTTP Server</h1></body></html>"); 4
但是不知道原理是为什么,希望知道的大神能给解释一下
send_new(client_sockfd,"HTTP/1.0 200 OK\r\n\r\n");
send_new(client_sockfd,"<!DOCTYPE html><html><head></head><body><h1>HTTP Server</h1></body></html>");
查看网页源代码
感谢回复,网页源代码已经很清楚了,是我自己写的字符串呀。
文档格式是否正确(要让浏览器以html解析,看起来就没写文档类型)?
代码中的编码是否正确?(比如都是string,c是默认asc的,比如其他ide出来的可能是utf8)
文档是否编码处理?([url encode],html encode)
1、应该跟文档类型没有关系,因为python这边返回的一样的字符串 ,就可以被浏览器解析
<html><head></head><body><h1>HTTP Server</h1></body></html>
2、编码问题我试着这样声明字符串 :
char html[] = u8"..."
不知道对不对(之前接触c的机会比较少),而且如果能在浏览器中显示正确字符应该就不是编码的问题吧
@xiaoxiao刀:
char html[] = u8"..."
不是这个意思的编码,比如MFC中有LChar、TChar...编码是不一样的,是程序本身的字符串编码。然后才是http 协议内的编码(url编码,html编码)。
@xiaoxiao刀: 浏览器比较高层,这种低级的测试,你可以直接用16进制打出来就清楚了。一眼就对比出来了。
头前面不应该有空行吧,换行表示正文开始了。
嗯 我把前面的换行去掉之后 浏览器就干脆获取不到信息了
@xiaoxiao刀: 2333
因为你HTTP版本大于1.0,所以要告诉浏览器,你内容格式,和内容长度,等。
建议看一下HTTP协议。
@长蘑菇星人:
我明白你的意思 ,可是有个问题,这是我用python实现的 http server
import os import socket import time SERVER_ADDRESS = (HOST, PORT) = '', 8888 REQUEST_QUEUE_SIZE = 5 def handle_request(client_connection): request = client_connection.recv(1024) print( 'Child PID: {pid}. Parent PID {ppid}'.format( pid=os.getpid(), ppid=os.getppid(), ) ) print(request.decode()) http_response = b"""\ HTTP/1.1 200 OK \n \n <html><head></head><body><h1>HTTP Server</h1></body></html> """ client_connection.sendall(http_response) # time.sleep(60) def serve_forever(): listen_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) listen_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) listen_socket.bind(SERVER_ADDRESS) listen_socket.listen(REQUEST_QUEUE_SIZE) print('Serving HTTP on port {port} ...'.format(port=PORT)) print('Parent PID (PPID): {pid}\n'.format(pid=os.getpid())) while True: client_connection, client_address = listen_socket.accept() pid = os.fork() if pid == 0: # child listen_socket.close() # close child copy handle_request(client_connection) client_connection.close() os._exit(0) # child exits here else: # parent client_connection.close() # close parent copy and loop over if __name__ == '__main__': serve_forever()
返回的字符串是一样的,最后结果:
@长蘑菇星人:
感觉应该是二楼说的,c语言的问题,但具体哪里错了 还不清楚
http协议还没搞清楚哦。快去看看
看过了 也按照http的格式改了很多次 最后没效果才放上来的
@xiaoxiao刀: http://phl.iteye.com/blog/1876867
吧该加的header 头加上。没有contentlength 不知道解析。第一行不要有任何字符换行,空格什么的
@calvinK:
好的 我试试。 但是为什么python 返回的同样的数据却行呢?
@xiaoxiao刀: tcp抓包看看呗
@calvinK:
还是老样子 不显示任何数据
下面是我telnet 返回的数据 数据格式看着没什么问题
@xiaoxiao刀: 看着没问题,浏览器F12 response有东西么。没有就还是解析有问题。可以c和py的tcp抓包看看
length 有145吗?我数了一下,貌似不够。。。。
@calvinK:
有空格换行符之类的 都算进去
@xiaoxiao刀: content-length 只是<html>....这一部分哦
@calvinK:
问题已经解决跟响应头的设置没有关系