Как будет на одном ip и на одном 80 порту работать два сайта?
Браузер, запрашивая сайт, шлёт заголовки запроса. В числе прочих, заголовок Host, в котором домен запрашиваемого сайта.

Веб-сервер, получая запрос, видит этот заголовок и принимает решение, какой контент отдать — сайт с соответствующим доменом, или, к примеру, заглушку по-умолчанию.

Как, упрощённо, выглядит диалог браузера с сервером:// юзер вводит адрес http://qna.habr.com/
// браузер ресолвит это имя в IP адрес и подключается к нему по порту 80
// браузер шлёт запрос:
GET / HTTP/1.1
Host: qna.habr.com
Accept-Language: ru

// сервер, видя такое дело, соображает, что речь про сайт qna
// и что надо отдать корневую страницу
// отдаёт контент QnA
Запрос на этот же порт на этом же IP для, скажем, сайта freelance.habr.com выглядел бы похоже:// юзер вводит адрес http://freelance.habr.com/
// браузер ресолвит это имя в (тот же) IP адрес и подключается к нему по порту 80
// браузер шлёт запрос:
GET / HTTP/1.1
Host: freelance.habr.com
Accept-Language: ru

// сервер понимает, что речь про сайт freelance
Добавлю к ответу Сергей Соколов, что со времен древнего апача (веб сервер Apache) технология реализации этого традиционно называется Virtual Hosts. В nginx, например, такого специального понятия или директивы нет, просто в блоках server указывается нужный домен в server_name.

Отделяет друг от друга запросы на разные сайты веб сервер действительно по заголовку Host.

Ну и на всякий случай: с https все чуть сложнее.