LINUX.ORG.RU

Помогите разобраться с sendto

 ,


0

1

Есть такая вот функция

int send_sres(uint8_t *rand, char *imsi, uint8_t *sres)
{

	//const char* cmdPath = DEFAULT_CMD_PATH;

	//char rspPath[200];
	//sprintf(rspPath,"/tmp/OpenBTS.console.%d.%8lx",getpid(),time(NULL));


	//printf("command socket path is %s\n", cmdPath);


	// the socket
	int sock = socket(AF_INET,SOCK_DGRAM,0);
	if (sock<0) {
		perror("opening datagram socket");
		exit(1);
	}
	FILE *bts_addr;
	bts_addr = fopen(DEFAULT_BTS_ADDR,"r");
	if(bts_addr == NULL)
		perror("Error while loading bts_addr file\n");
	char *inaddr=NULL;
	size_t inaddr_len=0;
	getline(&inaddr,&inaddr_len,bts_addr);
	fclose(bts_addr);
	// destination address
	struct sockaddr_in cmdSockName;
	memset(&cmdSockName, 0, sizeof(struct sockaddr_in));
	cmdSockName.sin_family = AF_INET;
   	cmdSockName.sin_addr.s_addr = inet_addr(inaddr);
   	printf("Server addr %s\n", inaddr); 
   	cmdSockName.sin_port = htons(5065); 
	

	// locally bound address
	struct sockaddr_in rspSockName;
	memset(&rspSockName, 0, sizeof(struct sockaddr_in));
	rspSockName.sin_family = AF_INET;
	rspSockName.sin_addr.s_addr = inet_addr("127.0.0.1");
	rspSockName.sin_port=htons(5066);
	
	if (bind(sock, (struct sockaddr *) &rspSockName, sizeof(struct sockaddr_in))) {
		perror("binding name to datagram socket");
		free(inaddr);
		exit(1);
	}
	

		char *randc;  //fgets(inbuf,199,stdin);
		//char *cmd; 
		char buf[128];

		randc=osmo_hexdump_nospc(rand,16);

		 strcat(strcat(strcat(strcpy(buf, "getsres "), imsi), " "), randc);
		 printf("rand : %s\n",buf);


	

		// use the socket
		if (sendto(sock, buf, sizeof(buf),0,(struct sockaddr*)&cmdSockName,sizeof(struct sockaddr))<0) {
			perror("sending datagram");
			printf("Error sent to socket\n");
		}
		else{
			printf("We successfully sended rand\n");	
		}

		const int bufsz = 100000;
		char resbuf[bufsz];
		int nread = recv(sock,resbuf,bufsz-1,0);
		if (nread<0) {
			perror("receiving response");
		}
		resbuf[nread] = '\0';
		printf("%s\n",resbuf);
		if (nread==(bufsz-1)) printf("(response truncated at %d characters)\n",nread);
	 	osmo_hexparse(resbuf,sres,4);
	free(inaddr);	
	close(sock);

}
Попытка выполнения заканчивается следующим
rand : getsres 250016387796246 89eef4f1949bb3d686fc49179d415847
sending datagram: Invalid argument
Error sent to socket

В чем дело, какой из аргументов левый?

★★★

Последнее исправление: cetjs2 (всего исправлений: 2)

Можно попробовать заменить sizeof(struct sockaddr) на sizeof(cmdSockName), смысл этого параметра в версионировании структуры по её размеру, иначе размер sockaddr можно было бы и не передавать, функция его и так бы знала.

xaizek ★★★★★
()
Ответ на: комментарий от LIKAN

Я проглядел суффикс, там всё правильно было.

xaizek ★★★★★
()
Ответ на: комментарий от mv

Вот такое я там увидел

bind(17, {sa_family=AF_INET, sin_port=htons(5066), sin_addr=inet_addr("127.0.0.1")}, 16) = 0
write(1, "rand : getsres 250016387796246 7"..., 64rand : getsres 250016387796246 7af17c471f123ebc87578f07e610eafd
) = 64
sendto(17, "getsres 250016387796246 7af17c47"..., 128, 0, {sa_family=AF_INET, sin_port=htons(5065), sin_addr=inet_addr("192.168.2.72")}, 16) = -1 EINVAL (Invalid argument)
write(2, "sending datagram: Invalid argume"..., 35sending datagram: Invalid argument
) = 35
write(1, "Error sent to socket\n", 21Error sent to socket
)  = 21
recvfrom(17, 

LIKAN ★★★
() автор топика

В чем дело, какой из аргументов левый?

Адрес назначения (тут его не видно, но скорее всего он не на loopback интерфейсе).

Deleted
()
Ответ на: комментарий от Deleted

Как не видно, там тупо айпишник написан. Вот если отмотать чуть-чуть пораньше

write(1, "Server addr 192.168.2.72\n", 25Server addr 192.168.2.72
) = 25
write(1, "\n", 1
)                       = 1
bind(17, {sa_family=AF_INET, sin_port=htons(5066), sin_addr=inet_addr("127.0.0.1")}, 16) = 0
write(1, "rand : getsres 250016387796246 7"..., 64rand : getsres 250016387796246 7af17c471f123ebc87578f07e610eafd
) = 64
sendto(17, "getsres 250016387796246 7af17c47"..., 128, 0, {sa_family=AF_INET, sin_port=htons(5065), sin_addr=inet_addr("192.168.2.72")}, 16) = -1 EINVAL (Invalid argument)
write(2, "sending datagram: Invalid argume"..., 35sending datagram: Invalid argument
) = 35
write(1, "Error sent to socket\n", 21Error sent to socket
)  = 21
recvfrom(17, 
В переменной inaddr храниться тупо строка «192.168.ххх.ххх» А как надо?

LIKAN ★★★
() автор топика
Ответ на: комментарий от LIKAN

В переменной inaddr храниться тупо строка «192.168.ххх.ххх»

Нет, там хранится другая строка, с переводом строки.

А как надо?

Надо без перевода строки.

Sorcerer ★★★★★
()
Ответ на: комментарий от LIKAN

Как не видно, там тупо айпишник написан.

Когда я свой пост писал, трейса не видел.

В переменной inaddr храниться тупо строка «192.168.ххх.ххх» А как надо?

«127.xxx.xxx.xxx». Или убрать bind, который выше по коду.

Deleted
()
Ответ на: комментарий от Deleted

Перевода строки там и нет. Я посылаю на удаленную машину, так что 127.xxx.xxx.xxx не катит.

LIKAN ★★★
() автор топика
Ответ на: комментарий от mv

Я бегло просмотрел man по bind. Я не вижу, как указать интерфейс. На моей машине пакеты в сеть отправляеются через eth1 (целью для моего приложения является удаленная машина в той же подсети).

LIKAN ★★★
() автор топика
Ответ на: комментарий от mv

Эмм, в коде это должно выглядеть как-то так

struct sockaddr_in rspSockName;
	memset(&rspSockName, 0, sizeof(struct sockaddr_in));
	rspSockName.sin_family = AF_INET;
	rspSockName.sin_addr.s_addr = inet_addr("127.0.0.1");
	rspSockName.sin_port=htons(5066);
	
	if (bind(sock, (struct sockaddr *) &rspSockName, sizeof(struct sockaddr_in))) {
		perror("binding name to datagram socket");
		free(inaddr);
		exit(1);
	}
struct sockaddr_in rspSockName;
	memset(&rspSockName, 0, sizeof(struct sockaddr_in));
	rspSockName.sin_family = AF_INET;
	rspSockName.sin_addr.s_addr = inet_addr("0.0.0.0");
	rspSockName.sin_port=htons(5066);
	
	if (bind(sock, (struct sockaddr *) &rspSockName, sizeof(struct sockaddr_in))) {
		perror("binding name to datagram socket");
		free(inaddr);
		exit(1);
	}

LIKAN ★★★
() автор топика
Ответ на: комментарий от LIKAN

есть константа INADDR_ANY, её и надо использовать вместо inet_addr(«0.0.0.0»)

Harald ★★★★★
()
Ответ на: комментарий от mv

Только вот какая связь между sendto и bind? Я же использую совсем разные контексты.

LIKAN ★★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.