Error in binding a UDP socket - sockets

I have a program which goes this way.
{
memset(&hints, 0, sizeof(struct addrinfo));
/* fill the hints struct */
hints.ai_flags = AI_PASSIVE;
hints.ai_socktype = SOCK_STREAM;
//hints.ai_socktype = SOCK_DGRAM;
hints.ai_protocol = 0;
//hints.ai_protocol = IPPROTO_UDP;
hints.ai_canonname = NULL;
hints.ai_addr = NULL;
hints.ai_next = NULL;
if(iFamily == AF_INET)
hints.ai_family = AF_INET;
else if(iFamily == AF_INET6)
hints.ai_family = AF_INET6;
/* Code for getting gettaddressinfo */
if(iFamily == AF_INET)
{
iRet = bind(SockIPC, res->ai_addr, sizeof(struct sockaddr_in));
char sBuff[1024];
sprintf(sBuff, "errno [%d] ", errno);
fp=fopen("debug.log","a+");
fprintf(fp,"IPv4 bind error\n ");
fprintf(fp,"bind error = %s\n",sBuff);
fclose(fp);
fflush(stdout);
}
}
In the above piece of code I am trying to bind a UDP socket created.
I am getting the following bind error
bind error = 266
Which is address already in use.
Can anyone
let me know where I am going wrong.

There's no evidence of a problem here. It's only valid to evaluate errno if the immediately prior system call has returned -1, and perror("bind"); would have been a lot simpler:
if (bind(...) == -1)
{
perror("bind");
}
else // continue with execution
However there almost certainly was an error, if not 266: EADDRINUSE is 98, not 266. SOCK_STREAM and IPPROTO_UDP don't go together. You need SOCK_DGRAM and IPPROTO_UDP.

Related

Raw socket not receiving UDP packet

I wrote an application using raw sockets that creates a UDP packet and sends to a destination. The application is working fine and I even saw the packet sent using Wireshark. Now, I want that packet to be captured by another application on the destination system. I want to be able to access the UDP header on the destination system. So, I created a receiver using raw sockets on dest system. But, I'm not able to receive the packet to my application. I'm able to capture the packet using SOCK_DGRAM socket, but not with raw socket.
I remember reading that raw sockets doesn't have the concept of ports. Can anyone explain me exactly what's going on the dest system, how the demultiplexing at transport layer works and how the protocol field of ip header effects the transport layer functionality?
Sender code:
int main(void){
char message[] = "This is something very useful";
int sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_UDP);
if(sockfd < 0){
perror("Error creating socket");
exit(1);
}
struct sockaddr_in this, other;
this.sin_family = AF_INET;
other.sin_family = AF_INET;
this.sin_port = htons(9000);
other.sin_port = htons(8000);
this.sin_addr.s_addr = INADDR_ANY;
other.sin_addr.s_addr = inet_addr("127.0.0.1");
if(bind(sockfd, (struct sockaddr *)&this, sizeof(this)) < 0){
printf("Bind failed\n");
exit(1);
}
char packet[64];
memset(packet, 0, 64);
struct udphdr *udph = (struct udphdr *) packet;
strcpy(packet + sizeof(struct udphdr), message);
udph->uh_sport = htons(8080);
udph->uh_dport = htons(8000);
udph->uh_ulen = htons(sizeof(struct udphdr) + sizeof(message));
udph->uh_sum = 0;
if(sendto(sockfd, packet, sizeof(struct udphdr) + sizeof(message), 0, (struct sockaddr *) &other, sizeof(other)) < 0)
perror("Error");
else
printf("Packet sent successfully\n");
close(sockfd);
return 0;
}
Receiver code:
int main(void){
int sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_UDP);
char message[64];
if(sockfd < 0){
perror("Error creating socket");
exit(1);
}
struct sockaddr_in this;
this.sin_family = AF_INET;
this.sin_port = htons(8000);
this.sin_addr.s_addr = INADDR_ANY;
if(bind(sockfd, (struct sockaddr *)&this, sizeof(this)) < 0){
printf("Bind failed\n");
exit(1);
}
if(recv(sockfd, message, 64, 0) < 0){
perror("Error");
exit(1);
}
printf("\n\n%s\n\n", message);
close(sockfd);
return 0;
}

send_to returns EINVAL in udp

I am creating a simple file transfer application, but send_to is returning EINVAL when i am trying to send from server side to client, while both send_to and recv_from are working fine on the client side.
port_number, portno, hostname are passed as arguments.
Code to set up server:
portno=port_number;
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if (sockfd < 0)
error("ERROR opening socket");
optval = 1;
setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR,
(const void *)&optval , sizeof(int));
bzero((char *) &serveraddr, sizeof(serveraddr));
serveraddr.sin_family = AF_INET;
serveraddr.sin_addr.s_addr = htonl(INADDR_ANY);
serveraddr.sin_port = htons((unsigned short)portno);
if (bind(sockfd, (struct sockaddr *) &serveraddr,
sizeof(serveraddr)) < 0)
error("ERROR on binding");
//getsockname(sockfd, (struct sockaddr *)&clientaddr, &clientlen);
cout<<"server port no"<<serveraddr.sin_port<<endl;
clientlen = sizeof(clientaddr);
Code to set up client:
hostname = name;
portno = port;
/* socket: create the socket */
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if (sockfd < 0)
error("ERROR opening socket");
/* gethostbyname: get the server's DNS entry */
server = gethostbyname(hostname);
if (server == NULL)
{
fprintf(stderr,"ERROR, no such host as %s\n", hostname);
exit(-1);
}
/* build the server's Internet address */
memset((char *) &serveraddr,0, sizeof(serveraddr));
serveraddr.sin_family = AF_INET;
bcopy((char *)server->h_addr,
(char *)&serveraddr.sin_addr.s_addr, server->h_length);
serveraddr.sin_port = htons(portno);
serverlen = sizeof(serveraddr);
struct timeval tv;
tv.tv_sec = 1; // TIMEOUT IN SECONDS
tv.tv_usec = 0; // DEFAULT
if(setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) < 0)
printf("Cannot Set SO_RCVTIMEO for socket\n");
Command that is failing:
if(sendto (sockfd, ack, strlen(ack), 0,(struct sockaddr*)
&clientaddr,sizeof(clientaddr) < 0)
error("ERROR in sending hello_ACK");
where clientadddr is declared as struct sockaddr_in
EINVAL error is generated because of an invalid argument. So you should either initialize the clientaddr as you have done for serveraddr or if you are receiving a HELLO message earlier/ or any other message from the client you can pass clientaddr as an argument to that recvFrom call.
recvfrom(socketFileDescriptor, buffer, bufferSize,0,(struct sockaddr *) &clientaddr, &clientlen))
here the clientlen is sizeof(clientaddr) if you are writing in C.

Not able to make connection to a server process located on different network using in C

I am trying to send messages between two system located on different network using C socket programming.
But when connect() system call initiated it is returning -1 so I am not able to connect to the server.
How can I get connect to a remote server located on different network or different machine. Same program is working when I am using client and server on local machine.
**Client code ----->**
int main(int argc, char *argv[]){
int sockfd,portno,n;
char buffer[256];
struct sockaddr_in serv_addr;
struct hostent *server;
if (argc<3)
error("error port number not provided");
portno = atoi(argv[2]);
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if(sockfd<0)
error("error while creating socket ");
server =(struct hostent *)gethostbyname(argv[1]);
if(server == NULL){
fprintf(stderr,"ERROR, no such host\n");
exit(0);
}
bzero((char *) &serv_addr, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
//bcopy((char *)server->h_addr,(char *)&serv_addr.sin_addr.s_addr, server->h_length);
serv_addr.sin_port=htons(portno);
if(connect(sockfd,(struct sockaddr*)&serv_addr,sizeof(serv_addr))<0)
error("error while connecting..");
while(strncpy(buffer,"bye",3)!=0){
bzero(buffer,256);
printf("\nYou:");
fgets(buffer,255,stdin);
//n= write(sockfd,buffer,strlen(buffer));
n=send(sockfd,(char*)&buffer,strlen(buffer),0);
if(n<0)
printf("message not delivered\n");
bzero(buffer,256);
//n= read(sockfd,buffer,255);
n= recv(sockfd,buffer,255,0);
printf("\nfrd:%s",buffer);
}
close(sockfd);
}
**Server code -->**
int main(int argc, char *argv[]){
int sockfd,listenfd,portno,clilen,n;
char buffer[256];
struct sockaddr_in serv_addr, cli_addr;
if (argc<2)
error("error port number not provided");
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if(sockfd<0)
error("error while creating socket ");
bzero((char*) &serv_addr, sizeof(serv_addr));
portno = atoi(argv[1]);
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = INADDR_ANY;
serv_addr.sin_port = htons(portno);
if(bind(sockfd,(struct sockaddr*)&serv_addr,sizeof serv_addr)<0)
error("error while binding socket");
listen(sockfd`enter code here`,5);
clilen = sizeof(cli_addr);
if ((listenfd = accept(sockfd, (struct sockaddr*)&cli_addr,&clilen))<0)
error("error while initializing listening");
printf("listening for connections..");
while(strncmp(buffer,"bye",3)!=0){
bzero(buffer,256);
//n= read(listenfd,buffer,255);
n= recv(listenfd,buffer,255,0);
if(n<0)
error("no message");
printf("\nfrd:%s",buffer);
printf("\nyou:");
fgets(buffer,255,stdin);
//n= write(listenfd,buffer,sizeof buffer);
n=send(listenfd,(char*)&buffer,strlen(buffer),0);
if(n<0)
printf("message not sent");
}
close(sockfd);
}
All of client code is the same as that in the server.
server =(struct hostent *)gethostbyname(argv[1]);
if(server == NULL){
fprintf(stderr,"ERROR, no such host\n");
exit(0);
}
argv1 contains the name of a host on the Internet, e.g. hsembedded.blogspot.in ;)
The function:
struct hostent *gethostbyname(char *name)
Takes such a name as an argument and returns a pointer to a hostent containing information about that host. The field char *h_addr contains the IP address. If this structure is NULL, the system could not locate a host with this name.
The mechanism by which this function works is complex, often involves querying large databases all around the country.
bzero((char *) &serv_addr, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
bcopy((char *)server->h_addr,
(char *)&serv_addr.sin_addr.s_addr,
server->h_length);
serv_addr.sin_port = htons(portno);
This code sets the fields in serv_addr. Much of it is the same as in the server. However, because the field server->h_addr is a character string, we use the function:
void bcopy(char *s1, char *s2, int length)
which copies length bytes from s1 to s2.
the error is actually due to absence of #include<netdb.h> in client code.

Can anyone guide me or suggest how to make a client for live media server streaming over HTTP

Can anyone guide me or suggest how to make a client using sockets for live media server streaming over HTTP, as I tried a lot but was not successful.
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdlib.h>
#include <stdio.h>
#include<conio.h>
// Need to link with Ws2_32.lib, Mswsock.lib, and Advapi32.lib
#pragma comment (lib, "Ws2_32.lib")
#pragma comment (lib, "Mswsock.lib")
#pragma comment (lib, "AdvApi32.lib")
//************All Declarations**********//
#define DEFAULT_BUFLEN 512000
#define DEFAULT_PORT "8000"
int __cdecl main(int argc, char **argv)
{
WSADATA wsaData;
SOCKET ConnectSocket = INVALID_SOCKET;
struct addrinfo *result = NULL,
*ptr = NULL,
hints;
char *sendbuf = "this is a test";
char recvbuf[DEFAULT_BUFLEN];
int iResult;
int recvbuflen = DEFAULT_BUFLEN;
// Validate the parameters
if (argc != 2) {
printf("usage: %s server-name\n", argv[0]);
getch();
return 1;
}
// Initialize Winsock
iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
if (iResult != 0) {
printf("WSAStartup failed with error: %d\n", iResult);
getch();
return 1;
}
ZeroMemory( &hints, sizeof(hints) );
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
// Resolve the server address and port
iResult = getaddrinfo(argv[1], DEFAULT_PORT, &hints, &result);
if ( iResult != 0 ) {
printf("getaddrinfo failed with error: %d\n", iResult);
WSACleanup();
getch();
return 1;
}
// Attempt to connect to an address until one succeeds
for(ptr=result; ptr != NULL ;ptr=ptr->ai_next) {
// Create a SOCKET for connecting to server
ConnectSocket = socket(ptr->ai_family, ptr->ai_socktype,
ptr->ai_protocol);
if (ConnectSocket == INVALID_SOCKET) {
printf("socket failed with error: %ld\n", WSAGetLastError());
WSACleanup();
getch();
return 1;
}
// Connect to server.
iResult = connect( ConnectSocket, ptr->ai_addr, (int)ptr->ai_addrlen);
if (iResult == SOCKET_ERROR) {
closesocket(ConnectSocket);
ConnectSocket = INVALID_SOCKET;
continue;
}
break;
}
freeaddrinfo(result);
if (ConnectSocket == INVALID_SOCKET) {
printf("Unable to connect to server!\n");
WSACleanup();
getch();
return 1;
}
// Send an initial buffer
/*iResult = send( ConnectSocket, sendbuf, (int)strlen(sendbuf), 0 );
if (iResult == SOCKET_ERROR) {
printf("send failed with error: %d\n", WSAGetLastError());
closesocket(ConnectSocket);
WSACleanup();
getch();
return 1;
}*/
printf("Bytes Sent: %ld\n", iResult);
// shutdown the connection since no more data will be sent
iResult = shutdown(ConnectSocket, SD_SEND);
if (iResult == SOCKET_ERROR) {
printf("shutdown failed with error: %d\n", WSAGetLastError());
closesocket(ConnectSocket);
WSACleanup();
getch();
return 1;
}
// Receive until the peer closes the connection
do {
iResult = recv(ConnectSocket, recvbuf, DEFAULT_BUFLEN, 0);
if ( iResult > 0 )
printf("Bytes received: %d\n", iResult);
else if ( iResult == 0 )
printf("Connection closed\n");
else
printf("recv failed with error: %d\n", WSAGetLastError());
} while( iResult > 0 );
// cleanup
getch();
closesocket(ConnectSocket);
WSACleanup();
return 0;
}
I tried the above code, it works well with a server I create. The problem is I am streaming an transport stream file from live media server through http,but when I try to receive the data from my code of client I am able to connect at specific url but could not receive anything.
The easiest solution for you would be to use the openRTSP client from liveMedia as a starting point. It pretty much comes down to implementing the entire RTSP stack as well interleaving the media over the TCP connection. By passing in the "-T " as a command line parameter, you can configure openRTSP to stream over RTSP over TCP. You can then write your own application based on openRTSP in which you can then handle incoming media samples as desired.
I would advise you against implementing this functionality yourself from a socket-level. You would need to implement RTSP, RTP, RTCP, RTSP over HTTP tunneling, SDP, the various RTP payload formats e.g. for H.264. You socket-related code segment above doesn't begin to touch the surface.
If you want to see what the protocol exchange looks like, sniff the traffic from openRTSP to an RTSP server using wireshark. You can also find an RTSP server at liveMedia.
If it's over HTTP you first have to send an HTTP request (and then parse the response). Example.
You don't receive anything because the server is waiting for the request.

bsd sockets connect timeout iPhone

How to write code which specifies timeout to BSD sockets connect syscall ? I writing iPhone application and i need to wait long time to get response from connect syscall. Any Examples ?
Thanks
Now i have something like this:
host_name = NULL ;
host_name = gethostbyname([[host_value hostname] UTF8String]) ;
if (host_name != NULL)
{
struct sockaddr_in sin;
sock = socket(AF_INET, SOCK_STREAM, 0);
sin.sin_family = AF_INET;
sin.sin_port = htons([[host_value port_number] intValue]);
memcpy((char *)&sin.sin_addr,(char*)host_name->h_addr,host_name->h_length);
if (connect(sock, (struct sockaddr*)(&sin),sizeof(struct sockaddr_in)) != 0)
{
/* code */
}
}
s = socket(AF_INET, SOCK_STREAM, 0);
int x;
x=fcntl(s,F_GETFL,0);
fcntl(s,F_SETFL,x | O_NONBLOCK);
From: http://rhoden.id.au/doc/sockets2.html