Аллен Питер В.
Шрифт:
char buffer[BUF_SIZE];
struct sockaddr_in sin, client;
sock1 = socket(AF_INET, SOCK_STREAM, 0);
memset((char *)&sin, '\0', sizeof(sin));
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = INADDR_ANY;
sin.sin_port = SERVER_PORT;
bind(sock1, (struct sockaddr *)&sin, sizeof(sin));
printf("Server running...\n");
listen(sock1, 3);
while (1) {
ans_len = sizeof(client);
sock2 = accept(sock1, &client, &ans_len);
write(sock2, MSG_TO_SEND, sizeof(MSG_TO_SEND));
total+=1;
ans_len = read(sock2, buffer, BUF_SIZE);
write(1, buffer, ans_len);
printf("Client no %d\n", total);
shutdown(sock2, 0);
close(sock2);
}
return 0;
}
Теперь разберемся, что есть что. Сначала мы определяем некоторые макросы: номер порта, который будет прослушивать сервер, размер буфера передаваемых данных и текст запроса клиенту.
Стандартные номера портов определены в файле
netinet/in.h
: enum {
IPPORT_ECHO = 7, /* Echo service. */
IPPORT_DISCARD = 9, /* Discard transmissions service. */
IPPORT_SYSTAT = 11, /* System status service. */
IPPORT_DAYTIME = 13, /* Time of day service. */
IPPORT_NETSTAT = 15, /* Network status service. */
IPPORT_FTP = 21, /* File Transfer Protocol. */
IPPORT_TELNET =23, /* Telnet protocol. */
IPPORT_SMTP = 25, /* Simple Mail Transfer Protocol. */
IPPORT_TIMESERVER = 37, /* Timeserver service. */
IPPORT_NAMESERVER = 42, /* Domain Name Service. */
IPPORT_WHOIS = 43, /* Internet Whois service. */
IPPORT_MTP = 57,
IPPORT_TFTP = 69, /* Trivial File Transfer Protocol. */
IPPORT_RJE = 77,
IPPORT_FINGER = 79, /* Finger service. */
IPPORT_TTYLINK = 87,
IPPORT_SUPDUP = 95, /* SUPDUP protocol. */
IPPORT_EXECSERVER = 512, /* execd service. */
IPPORT_LOGINSERVER = 513, /* rlogind service. */
IPPORT_CMDSERVER = 514,
IPPORT_EFSSERVER = 520,
/* UDP ports. */
IPPORT_BIFFUDP = 512,
IPPORT_WHOSERVER = 513,
IPPORT_ROUTESERVER = 520,
/* Ports less than this value are reserved
for privileged processes. */
IPPORT_RESERVED = 1024,
/* Ports greater this value are reserved
for (non-privileged) servers. */
IPPORT_USERRESERVED = 5000
}
; Нам понадобятся сразу два сокета: первый — это сокет сервера, а через второй сокет мы будем производить обмен данными с клиентом.
int sock1, sock2;
Следующие переменные:
ans_len
используется для хранения размера передаваемой клиентом информации — фактического размера структуры struct sockaddr_in, а total
— это счетчик числа клиентов, используемый для вывода порядкового номера клиента. Переменная
buffer
размера BUF_SIZE — это наш буфер для обмена информацией. Нам нужны две структуры типа sockaddr_in
— одна для сервера (sin) и одна для клиента (client). В строке
sock1 = socket(AF_INET, SOСK_STREAM, 0);
мы создаем наш, «серверный», сокет: набор протоколов — TCP/IP, режим — с установлением соединения.
Затем мы инициализируем структуру sin:
memset((char *)&sin, '\0', sizeof(sin));
sin.sin_family = AF_INET; // TCP/IP