DAVID Malan: Bây giờ chúng ta hãy nhìn vào thực tế phân phối mã trong tập tin gọi là server.c. Bây giờ hãy ghi nhớ rằng điều này khá lớn trong tuần này của tập tin. Đó là hơn 1.000 dòng mã nhưng hầu hết những dòng chúng tôi đã viết. Và những gì chúng tôi đã để lại là một vài khoảng trống mà bạn sẽ thấy cần điền vào để thêm một số nhất tính năng hấp dẫn của máy chủ web để thực sự có được nó bắt đầu. Thật vậy, nếu bạn chạy phân phối mã sau khi biên dịch nó bạn sẽ thấy rằng các máy chủ web không làm tất cả những gì nhiều. Thay vào đó, người dùng nhận được một 501, không được thực hiện, thông báo lỗi. Nhưng điều đó có ý nghĩa bởi vì cần chúng tôi đã thực sự không được thực hiện tất cả các chức năng của nó. Vì vậy, chúng ta hãy nhìn vào server.c. Và bạn sẽ muốn đi qua này trong một chi tiết nhỏ hơn, chậm hơn một chút, tốc độ của riêng bạn. Nhưng bây giờ hãy để tôi cố gắng để hướng dẫn bạn thông qua nó để cung cấp cho bạn một cảm giác của những gì là hữu ích để biết, những gì là ít hữu ích để biết, để bạn có thể hướng dẫn thăm dò của riêng bạn. Vì vậy, ở đầu server.c, tất nhiên, chúng tôi có một bó toàn bộ các định nghĩa. Cũng như toàn bộ một loạt các bao gồm. Đáng chú ý là chúng tôi có một vài hằng số toàn cầu ở đây, mà chúng tôi sử dụng trong mã của chúng tôi để làm cho đảm bảo rằng các mảng nhất định dài vừa phải. Dựa trên bao lâu chúng tôi yêu cầu HTTP hy vọng sẽ được tiếp nhận, khả năng, từ khách hàng web, hoặc các trình duyệt. Trong khi đó, chúng ta hãy di chuyển trên xuống ở đây, với một loại định nghĩa. Chú ý rằng giống như trong thiết P 4, nhờ đó mà chúng tôi đã chơi với tập tin I / O, tương tự như vậy ở đây, chúng tôi chơi với rất nhiều byte. Và vì vậy chúng tôi đã typedeffed char là một byte. Nói cách khác, các kiểu dữ liệu, vốn B-y-t-e, không tồn tại theo mặc định trong C. Vì vậy, chúng tôi đã tạo ra nó như là một từ đồng nghĩa với char để chúng tôi có một số giá trị 8-bit mà để làm việc. Bây giờ có một bó toàn bộ nguyên mẫu ở đây, một vài trong số đó là cho chức năng mà bạn sẽ viết, nhưng nhất của họ, chúng tôi đã viết bản thân mình. Hãy di chuyển xuống bây giờ để cuối cùng, chỉ một vài biến toàn cầu. Một là này sao char, AKA gốc. Thật vậy, bạn sẽ nhận thấy chúng tôi không bằng cách sử dụng thư viện CS50 nữa. Vì vậy, chúng tôi thay vì chỉ sử dụng sao char. Và gốc là có được một con trỏ đến chuỗi đó đại diện cho thư mục gốc của máy chủ. Vì vậy, ví dụ, khi tôi chạy các lệnh trước đó và chỉ định thư mục gốc của "công chúng", mà thư mục bên trong của phân phối Mã. Root, ở đây, sẽ là một con trỏ để chính xác chuỗi đó, "công cộng". Hoặc thực sự là đường dẫn đầy đủ / home / ubuntu / vv để mà thư mục công cộng. Trong khi đó, ở dòng 67 ở đây, chúng tôi có những gì được gọi là file descriptor. Đây là tinh thần tương tự nộp con trỏ sao. Nhưng hóa ra có của một tập hợp các chức năng bạn có thể sử dụng với đọc các tập tin hoặc đọc từ kết nối mạng. Giống như một web server web kết nối trình duyệt thực sự chỉ sử dụng số nguyên thay vì của con trỏ, như chúng ta đã thấy trên P đặt 4. Nhưng đó là ý tưởng tương tự. Và tôi đã thực hiện những toàn cầu để giữ theo dõi của một mô tả tập tin khách hàng. Giống như một con trỏ đến web của khách hàng của tôi. Và một mô tả tập tin máy chủ. Sắp xếp của một con trỏ đến máy chủ web, nhưng họ không thực sự con trỏ, họ chỉ là con số. Cuối cùng, chúng tôi có toàn cầu này biến ở đây được gọi là hiệu. Đó là cách của tôi, sự thật hay sai, giữ theo dõi xem người dùng có báo hiệu rằng anh ấy hoặc cô ấy muốn để ngăn chặn các máy chủ web. Và thực sự có một chức năng mà nghe cho kiểm soát C. Vì vậy, nếu bạn, người sử dụng, muốn giết các máy chủ bằng cách nhấn Control C, rằng biến boolean bạn sẽ thấy trong các mã được thiết lập là true. Và sau đó trong một vòng lặp chúng tôi giữ kiểm tra giá trị của biến đó. Và nếu đó là sự thật, chúng ta chỉ thoát khỏi chương trình hoàn toàn. Bây giờ chúng ta hãy nhìn vào chính. Bạn không cần phải hiểu tất cả mọi thứ trong main, nhưng chúng ta hãy cung cấp cho bạn một cảm giác của công việc tổng thể. Và sau đó có một cái nhìn gần hơn cho mình ở một số ý kiến. Ở nơi đầu tiên, một phần cách thức thông qua chính, chúng tôi phân tích các đối số dòng lệnh. Nó chỉ ra rằng chính là sẽ mong đợi một trong hai dấu gạch ngang h để được giúp đỡ, mà chỉ nói với bạn như thế nào để chạy các chương trình rất ngắn gọn. Hoặc dash p, cho phép bạn chỉ định một cổng. Nhưng một lần nữa, bằng cách sử dụng cổng 80 80, theo mặc định, là những gì bạn nên sử dụng CS 50 IDE. Tiếp theo, chúng ta chỉ cần làm một số kiểm tra lỗi. Đảm bảo rằng giá trị cổng thực sự là như chúng ta mong đợi, trong một phạm vi cụ thể. Và sau đó một số các phép thuật bắt đầu. Chúng tôi gọi chức năng này bắt đầu, mà chúng tôi đã viết. Chúng tôi đi vào với các cảng, như cũng như bất kỳ đối số tùy chọn để khởi động máy chủ. Cụ thể, rằng số cổng. Tất cả các quyền, tiếp theo, điều này là khá khó hiểu mã mà bạn sẽ không thấy quá thường xuyên, nhưng đó là một cách ưa thích của kể các chương trình để lắng nghe cho một tín hiệu. Một tín hiệu là một cái gì đó giống như một đột quỵ quan trọng đặc biệt, như Control C. Vì vậy, mã này ở đây là làm thế nào chúng ta đăng ký những gì được gọi là một sự kiện nghe. Theo đó, bất cứ lúc nào người dùng chạm Control C mã để báo cho máy tính để chạy một chức năng gọi là xử lý. Được viết dưới thấp hơn, thực hiện hạ thấp xuống trong tập tin này, server.c, mà dừng chương trình hoàn toàn. Nhưng không cần phải lo lắng về các chi tiết bên trong đó. Bây giờ chúng ta tập trung vào các vòng trong. Thật vậy, những gì các máy chủ web được làm là cố ý lặp vô hạn. Bởi vì sau khi tất cả đó là khá nhiều những gì bạn muốn có một máy chủ web để làm. Cho đến khi bạn rõ ràng ngăn chặn nó, bạn chỉ muốn ngồi đó hiệu quả trong vòng một, chờ đợi một người nào đó trên internet để kết nối với nó. Vì vậy mà các máy chủ web có thể sau đó đáp ứng một số yêu cầu. Bây giờ nhận thấy ở đầu của chương trình tôi miễn phí một số biến, bởi vì sau này bạn sẽ thấy chúng ta đang sử dụng malloc ở một số nơi. Vì vậy, tôi chỉ muốn làm cho chắc chắn tất cả các biến của tôi được khởi tạo với một số giá trị đã biết. Xuống đây tôi kiểm tra xem chương trình đã được báo hiệu. Nói cách khác, nếu người dùng nhấn Control C, chúng ta chỉ cần bỏ ra khỏi vòng lặp này bằng cách gọi ngừng. Và sau đó bây giờ mã này được một chút thú vị hơn. Nhưng chú ý rằng bạn không có để viết bất cứ điều gì trong chính. Thay vào đó, bên trong chính chúng ta làm như sau. Nếu người dùng có connected-- đây là một hàm chúng ta đã viết, mà trả về đúng hoặc sai. Và mỗi lần nó được gọi là nó chỉ nói, vâng, một khách hàng, một trình duyệt đã được kết nối với máy chủ. Hoặc, không, nó không có. Và bằng cách này có thể chúng ta chỉ vòng lặp vô hạn chờ đợi cho đúng để được trả lại bằng chức năng đó. Trong khi đó, chức năng tiếp theo này, yêu cầu, chúng tôi cũng đã viết cho bạn. Này có bất cứ điều gì là bên trong đó phong bì ảo, cái gọi là HTTP yêu cầu, và thực sự phân tích nó như vậy để nói chuyện. Nhìn vào nó trên xuống dưới, trái sang phải, và tải tất cả những dòng đầu tiên. Giống như các dòng get và bất cứ điều gì khác bên dưới nó, vào một biến chúng tôi đã được gọi là tin nhắn. Đối với một thông điệp HTTP. Và chúng tôi cũng đã nạp chiều dài của nó vào chiều dài. Bây giờ đây là một chút khác nhau. Vì vậy, chúng ta hãy có một cái nhìn nhanh chóng tại đây. Mặc dù bạn không phải thực hiện các yêu cầu, nó rất hữu ích, có lẽ, để hiểu làm thế nào nó hoạt động. Yêu cầu chức năng này dường như được dùng trong hai tham số, nhắn tin và chiều dài. Nhưng chú ý rằng tôi đang đi qua trong một ký hiệu cho cả tin nhắn và chiều dài. Nhưng nếu chúng ta di chuyển lên, những gì là thông điệp và chiều dài? Cũng nhận thấy thông điệp đó và chiều dài được khai báo bên trong của chính là một ngôi sao char. Và một kích thước t. Mà thực sự là chỉ một int, tương ứng. Vì vậy, những gì là tò mò ở đây, mặc dù, là nếu tin nhắn này là một ngôi sao char nhưng tôi đang đi qua trong ký hiệu của tin nhắn, đó là loại giống như công nghệ cao nhận được địa chỉ của một con trỏ. Một con trỏ đôi, nếu bạn sẽ. Và trên thực tế, nếu tôi di chuyển trên xuống. Đường xuống vào tập tin này, nơi yêu cầu được thực sự thực hiện, Tôi sẽ thấy những điều sau đây chữ ký, hoặc nguyên mẫu, cho chức năng này. Mà có lẽ bạn đã không nhìn thấy trước. Các chức năng yêu cầu trả về một bool. Đó có thể là quen thuộc. Nhưng cần chú ý đối số đầu tiên của nó. Nó được gọi là tin nhắn, nhưng tôi có thể đã gọi nó là bất cứ điều gì ở đây. Nhưng nó sao sao char. Và đây là loại một điều gọn gàng. Bởi vì tôi muốn chức năng này yêu cầu để cấp phát bộ nhớ Tuy nhiên cho lớn các yêu cầu HTTP là ở chỗ phong bì ảo mà nó nhận được từ trình duyệt, tôi muốn có thể trả về một chuỗi. Nhưng tôi cũng muốn có có thể trở lại một thời gian. Vì vậy, như bạn sẽ thấy trong đặc điểm kỹ thuật, C, tất nhiên, không thể trả lại nhiều giá trị. Và trong thực tế, tôi chỉ là trả lại một bool ở đây. Nhưng cũng giống như chúng ta đã thấy trong giảng dạy một khi trở lại bạn có thể trở lại hai giá trị nếu bạn vượt qua trong hai giá trị tham khảo. Hoặc bởi con trỏ. Vì vậy mà bạn có thể thực sự đi đến những địa chỉ, đưa giá trị đó, và hiệu quả thông qua này kênh trở lại, có thể nói, có thể một chức năng trở lại nhiều giá trị cho người gọi. Trong trường hợp này, yêu cầu có thể trở về ba giá trị. Kiểu trả thực tế của nó, một bool. Các tin nhắn, một ngôi sao char sao. Và chiều dài, kích thước t. Mà chỉ là một int. Bởi vì yêu cầu chức năng này có thể đi đến độ dài địa chỉ và đặt một giá trị đó. Và nó có thể đi đến các địa chỉ của tin nhắn và đặt một giá trị đó. Và bây giờ nên có ý nghĩa. Bởi vì mặc dù tin là một ngôi sao char sao, ngay sau khi bạn đến đó với thông điệp sao, như chúng ta đã thấy trước đây trong mã, những gì bạn sẽ tìm thấy? Bạn sẽ tìm thấy chờ đợi bạn ở đó, một đoạn bộ nhớ mà phải là một ngôi sao char. Hoặc địa chỉ của một chuỗi. Và đó là OK nếu bạn không hoàn toàn bọc tâm trí của bạn xung quanh đó quá nhanh. Nhưng xem xét rằng tất cả chúng ta đang làm là lấy địa chỉ của một con trỏ để chúng tôi có thể đến đó và thực sự đặt một con trỏ ở đó. Nhưng không phải lo lắng nếu đó không hoàn toàn chìm trong chỉ bây giờ. Biết ngay bây giờ rằng yêu cầu chức năng hiệu quả cung cấp cho bạn với những ba giá trị. Vì vậy, bây giờ chúng ta quay trở lại chính. Điều gì đang xảy ra tiếp theo, trong chính, là sau đây. Một khi tôi đã nhận bên trong của tin và chiều dài, hai giá trị mà tôi quan tâm. Sau đó chúng tôi đi trước và viết một số mã cho bạn rằng cho phép bạn đọc chỉ là những dòng đầu tiên. Cái gọi là yêu cầu dòng từ yêu cầu. Cụ thể, một cái gì đó như get / HTTP 1.1, và không có gì hơn. Vì vậy, có một bó toàn bộ header HTTP khác, thu hồi, mà một trình duyệt sẽ gửi từ một khách hàng đến một máy chủ. Chúng tôi chỉ cần bỏ qua tất cả những người như vậy mà tất cả các bạn nhìn thấy trên cửa sổ thiết bị đầu cuối, thu hồi, chỉ là một cái gì đó như, get / hello.HTML HTP / 1.1. Vì vậy, mặc dù nhận thấy, rằng những thủ đoạn chúng ta đang làm gì ở đây sẽ có ích, có lẽ, trong chức năng phân tích cú pháp của riêng bạn mà bạn sẽ thực hiện. Chú ý rằng tôi chỉ là khai báo một biến. Sẽ xảy ra là const, có nghĩa là, Tôi hứa sẽ không thay đổi điều này. Được gọi là đống cỏ khô. Sau đó, tôi khéo léo đặt tên kim biến tiếp theo của tôi, vì vậy mà tôi có thể nhìn proverbially một cây kim trong một đống cỏ khô, sử dụng một siêu tiện dụng chức năng gọi là str str. S-T-R S-T-R, mà mỗi người đàn ông của mình trang, hoặc mỗi reference.CS50.NET, cho phép bạn tìm kiếm một chuỗi trong một. Và đây là cách của tôi tìm kiếm sự kết thúc của một dòng vì vậy mà tôi có thể thực sự đọc chỉ là một dòng vào bộ nhớ. Trong khi đó, thông báo trên đường 176 ở đây, tôi thực sự bố trí đủ bộ nhớ cho dòng đó. Và sau đó sử dụng str và sao chép, và chỉ sử dụng một ký hiệu khung ray, Tôi lưu trữ trong mảng đó? Chính xác đó dòng đầu tiên. Trong thực tế, tôi chỉ nhảy qua một cách nhanh chóng các đặc điểm kỹ thuật cho vấn đề tập hợp sáu. Đừng đọc qua chi tiết này. Nhưng những gì bạn sẽ tìm thấy được dòng này cụ thể ở đây. Nhờ đó mà dựa trên đặc điểm kỹ thuật định nghĩa chính thức HTTP, chúng tôi xác định những gì đầu tiên dòng nên được từ bất kỳ trình duyệt đến một máy chủ bên trong đó cái gọi là phong bì ảo. Cụ thể, các trình duyệt nên đề cập đến một phương pháp, giống như một get, hoặc bài, hoặc tương tự. Sau đó, nghĩa là một không gian, đại diện ở đây chỉ với sp do đó nó là rõ ràng rằng chúng tôi thực sự muốn có một không gian ở đây. Sau đó yêu cầu mục tiêu đó sẽ là một cái gì đó giống như /hello.HTML. Tiếp theo là một không gian khác. Tiếp theo là một phiên bản. Đó sẽ là một cái gì đó giống như HTTP / 1.1. Tiếp theo là C-R-L-F. Đó là một từ viết tắt bạn sẽ nhìn thấy rất nhiều trong đặc tả. Và đây chỉ là một cách ưa thích của nói r xuyệc ngược, dấu gạch chéo ngược n. Nói cách khác, vận chuyển trở lại, dòng mới. Hoặc thức ăn đường. Vận chuyển trở lại, thức ăn đường. Đó là những gì C-R-L-F có nghĩa. Bây giờ, trong khi đó, nếu chúng ta quay trở lại mã của chúng tôi, chúng ta hãy xem những gì còn lại để bạn có thể làm. Bên trong chính, cuối cùng, có một cuộc gọi đến một chức năng phân tích cú pháp. Mục đích của việc phân tích cú pháp là để đi mà dòng đầu tiên, có nghĩa chúng tôi chỉ thấy trên các đặc điểm kỹ thuật, và trích xuất cái gọi là đường dẫn tuyệt đối và truy vấn. Bây giờ hãy nhìn vào spec cho những gì chúng tôi có nghĩa là bằng cách đó. Tuy nhiên trong ngắn câu chuyện dài, điều này ở đây, yêu cầu mục tiêu, là một chuỗi có thể được chia thành hai phần. Hoặc một đường dẫn tuyệt đối như /hello.HTML. Tiếp theo là một dấu hỏi tùy chọn. Và sau đó một cái gì đó giống như q bằng mèo, hoặc q bằng con chó, hoặc bất kỳ số lượng giá trị quan trọng cặp mà chúng ta thấy trong bài giảng là một phần của tham số của một yêu cầu HTTP. Vì vậy, những gì bạn sẽ cần làm là thực hiện phân tích cú pháp. Và tìm ra cách để lặp qua dòng, mà chỉ là đối số đầu tiên rằng chúng ta đang đi trong. Nhân vật cho nhân vật cho nhân vật. Chỉ có đi lên đến hết chuỗi đó. Tìm kiếm cho rằng đường dẫn tuyệt đối và tìm kiếm truy vấn. Và những gì tốt đẹp về một thực tế là chúng tôi đã đưa cho bạn trong tài liệu định nghĩa ngữ pháp này của dòng đầu tiên, ở đây bạn sẽ phải tìm ra, tốt, là những gì phương pháp. Là hợp lệ hay không? Và chúng tôi cho bạn trong spec khi nó là hoặc là không hợp lệ. Nhận được, ví dụ, sẽ có hiệu lực. Không gian sẽ được dễ dàng để kiểm tra. Chỉ cần sử dụng tuần hai phong cách hay vấn đề thiết lập hai kiểu chuỗi kiểm tra. Hoặc nhân vật kiểm tra. Yêu cầu mục tiêu là điều bạn sẽ muốn phân tích. Vì vậy, hãy nhìn vào spec cho những gì mong đợi ở đó. Và rồi cuối cùng, HTTP phiên bản, bạn chỉ muốn để chắc chắn rằng nó là một trong những phiên bản hỗ trợ như HTTP 1.1. Vì vậy, về cơ bản là một chức năng phân tích cú pháp của sẽ là một cơ hội chỉ cần đọc nhân vật điều này cho nhân vật cho nhân vật, hoặc chuỗi bằng chuỗi, đảm bảo rằng nó phù hợp với đặc điểm kỹ thuật này. Được rồi, trở lại chính. Hãy xem những gì còn lại. Vì vậy, giả sử bạn đã bây giờ thực hiện chức năng phân tích cú pháp của bạn. Chúng tôi đã phân tích ra từ nó cái gọi là đường dẫn tuyệt đối và truy vấn, những gì không chính bây giờ phải làm gì với điều này? Vâng, một, bạn sẽ thấy trong code mà chúng ta URL giải mã trong trường hợp trình duyệt có mã hóa nhất định ký tự đặc biệt và cách đặc biệt, chúng tôi đi trước và chuyển đổi những người trở lại với các nhân vật Ascii thích hợp. Sau đó chúng tôi đi trước và tìm ra nếu người dùng đã yêu cầu /hello.HTML, những tập tin làm họ thực sự nghĩa là gì? Nói cách khác, chúng ta cần phải tận gốc rễ của các máy chủ, rằng đường dẫn đến thư mục công cộng, và nối nó với một cái gì đó như thế, hello.HTML. Vì vậy mà chúng tôi có một lớn hơn chuỗi đó dẫn chúng ta chính xác đến tập tin thực tế về hello.HTML IDEs CS50 ổ cứng, hoặc đĩa. Tiếp theo, chúng ta kiểm tra các con đường thực sự tồn tại. Nếu không chúng ta ném một 404 lỗi cho người sử dụng. Và, trên thực tế, trong suốt mã của chúng tôi bạn sẽ thấy rất nhiều công dụng của lỗi này chức năng mà tôi, chúng mình đã viết, và đặc điểm kỹ thuật bạn đi qua. Đây chỉ là một cách để trở về một cái gì đó khác hơn 200 cho người dùng. Bây giờ xuống đây, tôi đi trước và hình dung ra là những gì người dùng đã yêu cầu một tập tin, hoặc một thư mục. Bởi vì nếu đó là một thư mục, tôi muốn làm một vài điều. Một, nếu người dùng truy cập một URL mà là cho một thư mục, nhưng không kết thúc bằng một dấu gạch chéo, vì những lý do thông thường, Tôi muốn chắc chắn rằng chúng ta thay đổi URL để thực sự kết thúc trong một dấu gạch chéo. Và như vậy bạn sẽ thấy trong nguồn mã mà chúng tôi đã đưa cho bạn, chúng ta buộc người dùng phải chuyển hướng đến không [? fu?] nhưng [? fu /,?] nếu họ đã thực hiện cái kia. Và xem các đặc điểm kỹ thuật cho phù hợp. Trong khi đó, chúng tôi kiểm tra một điều khác. Nếu người dùng đã truy cập một thư mục và thư mục đó chứa một tập tin gọi là index.html hoặc index.php, theo quy ước của con người chúng tôi không muốn để cho họ thấy nội dung của thư mục đó. Chúng tôi muốn cho họ thấy các nội dung của tập tin mặc định, index.html, hoặc index.php. Và do đó, các mã tôi đã nêu bật tại đây cuộc gọi một chức năng gọi là chỉ số mà chỉ đơn giản kiểm tra, không có tồn tại một tập tin ở đây gọi là index.html hoặc index.php. Nếu không, nếu không có những điều kiện áp dụng chúng ta chỉ cần gọi hàm danh sách, mà chúng tôi đã viết, mà theo nghĩa đen liệt kê các nội dung của một thư mục. Tất cả các quyền, và những gì nếu yêu cầu rằng trình duyệt của người dùng đã thực hiện không phải là một thư mục, nhưng đối với một tập tin? Vâng, đầu tiên chúng ta gọi một chức năng tra cứu. Đó là sẽ nói với các máy chủ, là này một JPEG, là này một tập tin HTML, là một này GIF, hoặc một số định dạng khác. Nếu vậy, nó sau đó sẽ kiểm tra, tốt, nó là một tập tin PHP. Nếu vậy, chúng tôi muốn gọi một chức năng gọi là giải thích, chúng ta đã viết, mà giải thích rằng tập tin PHP và thốt ra những kết quả. Hoặc, compellingly hơn, nếu nó là bất cứ điều gì khác, chúng ta hãy đi trước và chỉ cần chuyển các tập tin. Giống như GIF hoặc JPEG từ máy chủ cho người sử dụng, như thể họ yêu cầu một trang HTML, hình ảnh, hoặc bất kỳ số thứ khác. Cuối cùng, nếu không có gì khác có vẻ làm việc, chúng tôi chỉ cần đi để nói 501. Đó là 501, không được thực hiện tin nhắn, có nghĩa là các máy chủ chưa được hoàn thành.