我的router.c文件创建了2个套接字
第一种是绑定到端口并回答客户端
第二个是连接到已经绑定的端口(通过server.c文件)
并发送消息。
由于某种原因,sendto
行返回Invalid argument
错误。
请帮忙。
#include <sys/types.h>
#include <netinet/in.h>
#include <inttypes.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <strings.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#include <errno.h>
/* The Rounter represents through the server file(recv_udp.c).It transmitting from/to A(client) and C(another client)
by specific criteria (given in the assignment). */
int main(int argc, char *argv[])
{
/* Adding values that`ll be used for Q5*/
char serMsg [] = "Nice to hear from you,I am the server\n";
// char serMsg [] = "Good morning sun shine\n";
int serMsgLeng = strlen(serMsg)+1;
int error = -1;
char buff_A[200] = {'\0'};
char buff_C[200] = {'\0'};
// A value we get from the command prompt
float x;
float random, rand_num;
struct timeval tv;
tv.tv_sec = 3; /* 3 Seconds Time-out */
tv.tv_usec = 0;
/* Values that`ll receive for the socket I`ll open (as socket descriptor(an int) etc.) */
int socket_fd1,socket_fd2, cc, addrLenA, s_in2Size;
/* Randome number Raffled between the range of[0,1] */
double randNum;
/* Defining Structures for decleration of the server s_in= as serverAddr(local ip,and local port),
from_A = the address that the datagram was received from client A,
from_C-the address that the datagram was received from client C . */
struct sockaddr_in s_in1, s_in2;
// Defining Structures for handling the clients address(client A and client C)
// Client A address structure
struct sockaddr_in client_A_addr;
//Client C address structure
struct sockaddr_in client_C_addr;
x = atof(argv[1]);
// Creating UDPsocket-(it`s a system call)-the socket()function opens a local socket and saves it`s number in socket_fd value. */
socket_fd1 = socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP);
socket_fd2 = socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP);
/*set the socket options*/
setsockopt(socket_fd1, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof(struct timeval));
setsockopt(socket_fd2, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof(struct timeval));
// Binary cleaning /
bzero((char *) &s_in1, sizeof(s_in1)); /* They say you must do this */
bzero((char *) &s_in2, sizeof(s_in2));
/* Configure settings in address struct
"s_in.sin_family"-set the address family to be "AF_INET
"s_in.sin_addr.s_addr"- the htonl function converts host's to network's long
"s_in.sin_port" -the htons function converts regular form port to binary form.*/
s_in1.sin_family = (short)AF_INET;//host byte order
s_in1.sin_addr.s_addr = htonl(INADDR_ANY); // WILDCARD //
s_in1.sin_port = htons(1337);
s_in2.sin_family = (short)AF_INET;//host byte order
s_in2.sin_addr.s_addr = inet_addr("172.17.0.15"); // WILDCARD //
s_in2.sin_port = htons(1338);
// printsin( &s_in, "RECV_UDP", "Local socket is:");
fflush(stdout);
/* The bind function assigns a local protocol address to a socket(and another system call).
The purpose of sin here is to tell bind which local address to assign.
bind method input:the sock_fd and the stuctur that handels the address and it`s length*/
bind(socket_fd1, (struct sockaddr *)&s_in1, sizeof(s_in1));
printf("After binding,waiting to hear from clients!\n");
addrLenA = sizeof(client_A_addr);
s_in2Size = sizeof(s_in2);
connect(socket_fd2, (struct sockaddr *) &s_in2, s_in2Size);
printf("After connect to server!\n");
// Keep listenning
for(;;) {
// Check from who we recive the message - if from cilent A
// Check for errors
//recfrom() returns the length of the message that it receives,so if the client message length that the method returns is
//equal to the message length of client A - we raffel a number between[0,1].
if( (cc = recvfrom(socket_fd1,&buff_A,sizeof(buff_A),0,(struct sockaddr*)&client_A_addr,&addrLenA))== error){
printf("No message for now, waiting...\n");
}
// For self-check ,no error occured
if (strlen(buff_A) > 0) {
printf("Client A says: %s\n", buff_A);
// Than raffel a randNum and decide what to do with it(send or delete it)
srand(time(NULL));
random = rand();
rand_num = random / RAND_MAX;
printf("rand_num: %f\n", rand_num);
printf("x: %f\n", x);
// Greater than X send it
if(rand_num > x) {
printf("Sending message From A to C\n");
// Pass the message to C
if(sendto(socket_fd2, &buff_A, sizeof(buff_A),0,(struct sockaddr*)&client_C_addr,sizeof(client_C_addr))== error){
printf("sendto()- Client C failes to send message\n");
printf("%s\n", strerror(errno));
exit(1);
}
} else {
// Drop the message
}
// Clearing the message buffer
memset(buff_A, '\0', sizeof buff_A);
}
} //end for
return 0;
}
答案 0 :(得分:2)
您永远不会填写client_C_addr
。您必须告诉sendto
发送数据的位置,例如:
client_C_addr.sin_family = AF_INET;
client_C_addr.sin_port = htons(port);
client_C_addr.sin_addr.s_addr = inet_addr("192.168.1.1");