2015-11-21 4 views
0

Я пытаюсь сделать простой клиент SIP (UDP, сокеты BSD), но я застрял в сообщении REGISTER. Мне удастся отправить сообщение REGISTER звездочке, затем он ответит, но клиент не поймает ответ, поэтому он ждет навсегда.SIP-клиент не принимает ответ

#include <stdio.h> //printf 
#include <string.h> //memset 
#include <stdlib.h> //exit(0); 
#include <arpa/inet.h> 
#include <sys/socket.h> 
#include <sys/types.h> 
#include <ctype.h> 
#include <netinet/in.h> 
#include <unistd.h> 
#include <netdb.h> 

#define SERVER "127.0.0.1" 
#define BUFLEN 1024 //Max length of buffer 
#define PORT 5060 //The port on which to send data 


int main(int argc, char **argv) 
{ 
    struct sockaddr_in si_other; 
    int s,slen=sizeof(si_other); 
    char buf[BUFLEN]; 
    char message[]= "REGISTER sip:127.0.0.1 SIP/2.0\r\nVia: SIP/2.0/UDP 127.0.0.1:5060;branch=z9hG4bKnashds7\r\nFrom: <sip:[email protected]>;tag=as58f4201b\r\nCall-ID: [email protected]\r\nTo: <sip:[email protected]>\r\nCSeq: 1 REGISTER\r\nContact: <sip:[email protected]>\r\nAllow: INVITE,ACK,OPTIONS,BYE,CANCEL,SUBSCRIBE,NOTIFY,REFER,MESSAGE,INFO,PING\r\nExpires: 3600\r\n\r\n"; 

    if ((s=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) 
{ 
    fprintf(stderr, "socket failed"); 
    exit(1); 
} 

    memset((char *) &si_other, 0, sizeof(si_other)); 
    si_other.sin_family = AF_INET; 
    si_other.sin_port = htons(PORT); 

if (inet_aton(SERVER , &si_other.sin_addr) == 0) 
{ 
    fprintf(stderr, "inet_aton() failed\n"); 
    exit(1); 
} 
while(1){ 
if (sendto(s, message, strlen(message) , 0 , (struct sockaddr *) &si_other, slen)==-1) 
    { 
     fprintf(stderr, "sendto failed"); 
     exit(1); 
    } 
memset(buf,'\0', BUFLEN); 
if (recvfrom(s, buf, BUFLEN, 0, (struct sockaddr *) &si_other, &slen) == -1) 
    { 
     fprintf(stderr, "recvfrom() failed"); 
     exit(1); 
    } 
    } 
} 

Это только часть кода, который, как представляется, не получает данные.

+0

Я не знаю SIP, но 1. Вы не должны отправлять сообщение перед тем, как услышать (получать)? 2. Правильно ли использовать '\ n', а не \ r \ n', в середине' сообщения'? – MikeCAT

+0

Yop, я отправляю сообщение до получения, я просто не включил его в пример. И 2, я должен поставить новую строку после заголовка evey в сообщении. – Croolman

+0

s результат не инициализируется в вызове recvfrom. Если есть больше кода, отправьте его. –

ответ

0

Проблема была в заголовке сообщения. Часть Via должна заканчиваться ;rport, поэтому звездочка действительно сообщает.

0

Вы забыли привязать к гнезду:

if(bind(s , (struct sockaddr*)&si_other, sizeof(si_other)) == -1) 
    { 
     fprintf(stderr, "bind failed\n"); 
     exit(1); 
    } 
+0

Это клиент UDP, он не обязательно должен связываться. – Croolman

+0

Я пробовал код со связыванием и работает. Плюс: с UDP вы должны привязать() к сокету в клиенте, потому что UDP является без установления соединения, поэтому нет другого способа для стека узнать, какая программа для доставки датаграмм для определенного порта. См. (Http://stackoverflow.com/questions/3057029/do-i-have-to-bind-an-udp-socket-in-my-client-program-to-receive-data-i- всегда) –

Смежные вопросы