#c #linux #sockets #network-programming
#c #linux #сокеты #сетевое программирование
Вопрос:
Мой код завершается с ошибкой. Я запускаюсь от имени root (то же поведение, что и у обычного пользователя)
Сначала я хочу установить TOS, а затем получить значение.
int tos_local = 0x28;
if (setsockopt(sockfd, IPPROTO_TCP, IP_TOS, amp;tos_local, sizeof(tos_local))) {
error("error at socket option");
} else {
int tos=0;
int toslen=0;
if (getsockopt(sockfd, IPPROTO_TCP, IP_TOS, amp;tos, amp;toslen) < 0) {
error("error to get option");
}else {
printf ("changing tos opt = %dn",tos);
}
}
printf печатает
изменение tos opt = 0
Я бы ожидал напечатать 0x28 (40).
В чем проблема?
Правильный ответ:
if (setsockopt(sockfd, **IPPROTO_IP**, IP_TOS, amp;tos_local, sizeof(tos_local))) {
int tos=0;
int toslen=sizeof(tos); //that line here
if (getsockopt(sockfd, IPPROTO_IP, IP_TOS, amp;tos, amp;toslen) < 0) {
Комментарии:
1. 5-й аргумент getsockopt — это размер буфера, на который указывает 4-й аргумент. Поэтому вам нужно удалить amp; в вашем примере кода. Или, еще лучше, поместите туда sizeof (tos), как сказал Сет.
Ответ №1:
IP_TOS
имеет уровень IPPROTO_IP
, не IPPROTO_TCP
.
Смотрите документацию.
Это влияет как на настройку, так и на получение опции.
Кроме того, то, что Сет сказал об инициализации параметра length, который влияет только getsockopt
.
Комментарии:
1. Действительно. И IP_TOS оказывается равным 1, как и TCP_NODELAY , так что этот код действительно что-то делает… Просто не то, что было задумано.
2. @Nemo: Да, они должны были разработать их как битовые поля вместо отдельных параметров. Но это еще не все.
Ответ №2:
При вызове getsockopt вы передаете размер памяти, на который указывает amp;tos. Другими словами, инициализируйте toslen значением sizeof(tos).
Комментарии:
1. Я получаю предупреждение компилятора об ошибке: предупреждение: передача аргумента 5 getsockopt преобразует указатель из целого числа без приведения, когда я передаю sizeof (tos). Кроме того, сбой getsockoption с «неверным адресом»
2. @cateof: передача
amp;tos_len
в качестве параметра правильная, но вам нужно объявить его какint tos_len = sizeof (tos);
, а не0
как.3. @cateof: @Бен Войт: Я думаю, вы имеете в виду, что передача amp;tos_len в качестве параметра правильная, но вам нужно инициализировать его значением sizeof (tos), а не 0.