I am trying to make basic reliable connection over udp. I have defined the custom bind function which takes same kind of arguments as TCP bind but in my function during passing parameters I got the error message as below:
bind() failed: Address family not supported by protocol
I have defined the r_bind function in one file and is accessed from next file. The function is as below:
int r_bind(int sockfd, struct sockaddr *addr,socklen_t addrlen){
return bind(sockfd, (struct sockaddr*) &addr, addrlen);
}
typedef struct brp_socket{
int sockfd;
struct sockaddr_in brp_serveraddr;
struct sockaddr_in brp_useraddr;
}brp_socket;
I have made call from user1.c file. The socket was created successfully but during binding I got the error. I have made the following function call.
brp_socket socket_list[BRP_MAX_SOCKET];
int socket_index = 0;
int servSock; // Socket descriptor for server
servSock = r_socket(AF_INET, SOCK_BRP, 0)
socket_list[socket_index].sockfd = servSock;
memset(&socket_list[socket_index].brp_serveraddr, 0, sizeof(socket_list[socket_index].brp_serveraddr)); // Zero out structure
socket_list[socket_index].brp_serveraddr.sin_family = AF_INET; // IPv4 address family
socket_list[socket_index].brp_serveraddr.sin_addr.s_addr = htonl(INADDR_ANY); // Any incoming interface
socket_list[socket_index].brp_serveraddr.sin_port = htons(servPort); // Local port
if (r_bind(socket_list[socket_index].sockfd, (struct sockaddr*)&(socket_list[socket_index].brp_serveraddr), sizeof(socket_list[socket_index].brp_serveraddr)) < 0)
#define SOCK_BRP 1
int r_socket(int domain, int type, int protocol){
if(type == 1)
{
return socket(domain,SOCK_DGRAM,protocol);
}
}
Here BRP_SOCK is custom made protocol type.
Can anyone suggest me where I made the mistake?
Related
I have a variable of in_addr_t type and I would like to use connect() with the given ip. I'm therefore needing a (struct sockaddr *) variable as parameter for the connect(). How to insert use the in_addr_t variable instead?
in_addr_t var; // Given variable, not actually declared here ofc
int sockfd = socket(AF_INET, SOCK_STREAM, 0);
struct sockaddr_in *srvraddr = malloc(sizeof(struct sockaddr_in));
memset((void *) srvraddr, 0, sizeof(struct sockaddr_in));
srvraddr->sin_family = AF_INET;
srvraddr->sin_port = htons(PORT_A); // Big - little endian arch compatibility
srvraddr->sin_addr.s_addr = var; // Somehow assign var here? <<<<<
connect(sockfd, (struct sockaddr *) srvraddr, sizeof(struct sockaddr_in));
Whatever I try to do connect always returns me -1.
Using perror I get the following error: Connection refused.
How to insert use the in_addr_t variable instead?
You cannot use an in_addr_t with connect() instead of a struct sockaddr_in. connect() accepts varying address structure types, but not arbitrary ones. The correct structure type for an IPv4 address is the struct sockaddr_in that you're already using. You need to store an appropriate representation of the remote host address into that.
Evidently, you already have an in_addr_t that you assert represents the remote address, but are uncertain how to use it:
in_addr_t var; // Given variable, not actually declared here ofc
[...]
srvraddr->sin_addr.s_addr = var; // Somehow assign var here? <<<<<
What you present is already exactly what POSIX expects you to do, however. POSIX requires that the sin_addr member of a struct sockaddr_in be a structure having at minimum a s_addr member of type in_addr_t. Supposing that the in_addr_t you have is in fact a correct representation of the machine address to which you want to connect, assigning that value to sin_addr.s_addr of your address structure is just right. In principle, there could be more members of that struct, but in practice, implementations that want to be interoperable will not require you to set any other members. Most don't have other members at all.
Do note, however, that just because connect() receives the address structure via a pointer does not mean you need to use dynamic allocation. It would be a bit more idiomatic to do this:
int sockfd = socket(AF_INET, SOCK_STREAM, 0);
struct sockaddr_in srvraddr = { 0 };
srvraddr.sin_family = AF_INET;
srvraddr.sin_port = htons(PORT_A);
srvraddr.sin_addr.s_addr = var;
connect(sockfd, (struct sockaddr *) &srvraddr, sizeof(srvraddr));
Among other things, that saves you having to free the memory afterward.
Whatever I try to do connect always returns me -1. Using perror I get the following error: Connection refused.
As far as I can see, the code you've presented is fine. You may want to check how you are obtaining the in_addr_t value in the first place, and to verify the port number you are using. On the other hand, do not overlook the possibility that the problem is at the remote host: perhaps the port you are trying to connect to is just not open (to you).
This is my way of using connect() to get a connection to "example.com" on port 80:
#include <stdio.h>
#include <netdb.h>
#include <unistd.h>
int main(void)
{
int sockfd;
if ((sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1) {
fprintf(stderr, "socket");
return 0;
}
char domain[] = "example.com";
struct hostent *he;
he = gethostbyname (domain);
if (!he)
{
switch (h_errno)
{
case HOST_NOT_FOUND:
fputs ("The host was not found.\n", stderr);
break;
case NO_ADDRESS:
fputs ("The name is valid but it has no address.\n", stderr);
break;
case NO_RECOVERY:
fputs ("A non-recoverable name server error occurred.\n", stderr);
break;
case TRY_AGAIN:
fputs ("The name server is temporarily unavailable.", stderr);
break;
}
return 1;
}
if (he->h_length < 4)
return 1;
struct sockaddr_in srvraddr;
srvraddr.sin_len = sizeof(srvraddr);
srvraddr.sin_family = AF_INET;
srvraddr.sin_port = htons(80);
srvraddr.sin_addr = * (struct in_addr *) he->h_addr_list[0];
if (connect(sockfd, (struct sockaddr*)&srvraddr, srvraddr.sin_len) == -1) {
fprintf(stderr,"connect() failed\n");
return 1;
}
// Use conection here...
close(sockfd);
return 0;
}
I'm writing a simple server code.
After running the code,I'm trying to connect the server using "telnet localhost 8000" and I get the next error: "Connection closed by foreign host" and the server closes.
this is the code I wrote:
void main(int argv,void * argc)
{
//int socket(int af, int type, int protocol);
int listen_sckt;
int new_socket;
int addrlen;
struct sockaddr_in addr;
/*
#include <netinet/in.h>
struct sockaddr_in {
short sin_family; // e.g. AF_INET
unsigned short sin_port; // e.g. htons(3490)
struct in_addr sin_addr; // see struct in_addr, below
char sin_zero[8]; // zero this if you want to
};
struct in_addr {
unsigned long s_addr; // load with inet_aton()
};
*/
listen_sckt = socket(AF_INET,SOCK_STREAM,0);
if(listen_sckt == -1){
perror("SOCKET ERR\n");
return;
}
printf("Socket succesfulyl opened\n");
{
/*
binding a docket
syntax:
int bind(int s, struct sockaddr *addr, int addrlen);
connect the socket to a logic port.
so the other side will know where to "find" the other side
*/
}
addr.sin_family = AF_INET;x`
addr.sin_addr.s_addr = INADDR_ANY;
addr.sin_port = htons(8000);
//binding command
if(-1 == bind(listen_sckt,(struct sockaddr*)&addr,sizeof(addr))){
perror("BINDING ERR\n");
}
printf("Binding succesfully done\n");
/* Listen()
Before any connections can be accepted, the socket must be told to listen
for connections and also the maximum number of pending connections using listen()
Includes:
#include <sys/socket.h>
Syntax:
int listen(int socket, int backlog);
socket - the socket file descriptor
backlog - the max number of pedding the socket will hold
C source:
*/
listen(listen_sckt,2);
/*
To actually tell the server to accept a connection, you have to use the function accept()
Includes:
#include <sys/socket.h>
Syntax:
int accept(int s, struct sockaddr *addr, int *addrlen);
*/
addrlen = sizeof(struct sockaddr_in);
new_socket = accept(listen_sckt,(struct sockaddr*)&addr,&addrlen);
if(new_socket<0){
perror("Accept ERR\n");
}
printf("Acept success\n");
}
Thanks.
That's because once you have accepted the connection, you exit the program which causes all descriptors (including sockets) to be closed.
If you want to do something with the socket, you should do that after the accept call. Like having a read/write loop.
And you should probably have a loop around the whole thing, so your program can accept new connections once the previous is closed.
I wrote a module for asterisk that needs to communicate to a service request information an return it, but for some reason my socket does not connect at all. When I telnet to the service it works fine, but I can not figure out why the it returns a -1 in the module
This is the code in my module
int SocketQuery(char buffer[BUFFSIZE],char *qrystr){
int sock;
struct sockaddr_in eserver;
int sockres = 0;
unsigned char receiving = 1;
memset(sendbuff,0,sizeof(sendbuff));
/* Create the TCP socket */
if ((sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
ast_log(LOG_ERROR,"Failed to create socket for LCRROUTER");
return -1;
}
/* Construct the server sockaddr_in structure */
memset(&eserver, 0, sizeof(eserver)); /* Clear struct */
eserver.sin_family = AF_INET; /* Internet/IP */
eserver.sin_addr.s_addr = inet_addr(IP); /* IP address */
eserver.sin_port = htons(port); /* server port */
/* Establish connection */
ast_log(LOG_NOTICE,"LCRROUTER - Connection to %s on port %s\n", IP, port);
sockres = connect(sock,
(struct sockaddr *) &eserver,
sizeof(eserver));
if (sockres < 0) {
ast_log(LOG_ERROR,"LCRROUTER - Failed to connect with server on %s:%s. Error Code %d", IP,port,sockres);
return -1;
}
sockres returns -1. Do I miss something?
You can use
tcpdump port YOUR_PORT_HERE -v -s0
In that form it will show you all packets sent via socket.
I'm new in sockets and I don't know if its possible to do what I'm trying. First of all, I've looked for more info in Google and in stackoverflow but I haven't found anything :(
Now I explain my problem. I have created client socket (with the functions socket y connect) in the main function with no problem. But then I call a function called sendframe() thet I've created, where I do some stuff and then I use the write function to put a message in the socket. The problem here is that I dont know why the write function gives an error (returns -1). I think the problem is that I haven't passed correctly the socket file descriptor, but I'm not sure (I'm not convinced that using only the file descriptor allows me to write in the socket...)
Here is a snippet of what I'm trying to do:
#include ...
void sendframe(int sockfd);
void main(void) {
//// Open the socket
int sockfd;
struct sockaddr_in serv_addr;
struct hostent *server;
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
error("open socket erorr\n");
server = gethostbyname("192.168.20.155");
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = 1414;
serv_addr.sin_addr = *((struct in_addr *) server->h_addr);
bzero(&(serv_addr.sin_zero),8);
if(connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(struct sockaddr))==-1)
error("connect error\n");
exit(-1);
// ..... More code.....
// Send frame
sendframe(&sockfd);
}
void sendframe(int sockfd)
{
// Some stuff...
char *frame
int num = write(sockfd,frame,strlen(frame));
}
Probably the answer is so easy, but I'm new in this. Any clue?
sendframe(&sockfd); should be sendframe(sockfd); as sendframe expects an int, not int *.
I try to make a client/server program in C with IPv6 and UDP. When the program binds the socket it return the WSAError 10049. I know that this is a problem with the adress name but don't see whats the problem. I hope someone can help.
struct sockaddr_in6 server, client;
SOCKET sock;
char buffer[BUFFERSIZE];
LPTSTR recvBuff[1024];
DWORD recvBuffLen = 1024UL;
int len = sizeof(client);
WORD wVersionRequested;
WSADATA wsaData;
wVersionRequested = MAKEWORD(1,1);
WSAStartup(wVersionRequested, &wsaData);
sock = socket(AF_INET6, SOCK_DGRAM, 0);
if (sock < 0)
error("Fehler beim Anlegen des Sockets");
server.sin6_family = AF_INET6;
server.sin6_port = htons(6000);
server.sin6_addr = in6addr_any;
if (bind(sock, (struct sockaddr *) &server, sizeof(server)) == -1)
error("Fehler beim binden des Sockets");
This normally results from an attempt to bind to an address that is not valid for the local computer..
You should use PF_INET here instead of AF_INET. They have the same value, but you're not specifying an address family AF here, you're specifying a protocol family PF. This is just a style recommendation.
I would suggest to memset zero the below arrays,structures:
struct sockaddr_in6 server, client;
SOCKET sock;
char buffer[BUFFERSIZE];
LPTSTR recvBuff[1024];
Before you can use the sockaddr_in6 struct, you will have to memset it to zero:
memset(server, 0, sizeof(struct sockaddr_in6));
The reason is that the struct sockaddr_in6 structure contains other fields which you are not initializing (such as sin6_scope_id) and which might contain garbage.
I have faced the same error.
#askMish 's answer is quite right.I didn't understand it at the first place,however I find it out eventually.
This normally results from an attempt to bind to an address that is not valid for the local computer..
Normally we have our computer under some gateway.
If we run ipconfig we will find the IP address is 192.168.something.
So that's the IP we could use to bind in code.
While other should connect with the public IP(if you can surf Internet you have one for sure.) like 47.93.something if they are in the same LAN with you.
You need to find that IP at your gateway(possibly your family's route).
I had that same error code when calling bind() under windows.
The reason in my case was not the same as in the initial poster's code, but i guess other will have made the very same mistake as me:
I generated the local address on which i want the server to be bound locally using the inet_addr()-function.
I assigned this result to the local address structure struct sockaddr_in localaddr this way:
localaddr.sin_addr.s_addr = htonl(inaddr);
But inet_addr() already returns the address in byte-network-order, so the call htonl(inaddr) was wrong in my code and caused error 10049:
SOCKET tcpsock_bindlisten(unsigned short port, const char* bindaddr)
{
SOCKET srvsock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
unsigned long inaddr = bindaddr ? inet_addr(bindaddr) : INADDR_ANY;
struct sockaddr_in localaddr;
memset(&localaddr, 0, sizeof(struct sockaddr_in));
localaddr.sin_family = AF_INET;
localaddr.sin_port = htons(port);
// ERROR HERE! address returned from inet_addr is already in network-byte-order!
localaddr.sin_addr.s_addr = htonl(inaddr);
// CORRECT THIS WAY:
localaddr.sin_addr.s_addr = inaddr;
if (bind(srvsock, (struct sockaddr *) &localaddr, sizeof(localaddr)) != 0)
{
print_socketerror("tcpsock bind()");
return INVALID_SOCKET;
}
if (listen(srvsock, SVRSOCK_BACKLOG) != 0)
{
print_socketerror("tcpsock listen()");
return INVALID_SOCKET;
}
return srvsock;
}
When calling bind() using "all local interfaces" (INADDR_ANY) it worked, because of this coincidence INADDR_ANY == htonl(INADDR_ANY):
int main()
{
...
// this works for this special case:
SOCKET svrsock1 = tcpsock_bindlisten(4444, NULL);
// did not work!
SOCKET svrsock2 = tcpsock_bindlisten(5555, "192.168.0.123");
}