I'm new to socket programming and I am trying to write a simple socket that connects to another socket on my PC (nc -l 35353)
I keep getting a error when trying to bind the socket and I don't know how to debug it.
UPDATE: The socket call is returning 0 as a file descriptor, although the man page does not say this is illegal, I thought unix/linux reserve fd 0, 1 and 2 for stdin, stdout and stderr by default. I am not sure if this has anything to do with the bind error I am seeing, I just felt this might be appropriate.
Here is the code
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<netinet/in.h>
#include<sys/types.h>
#include<sys/socket.h>
//typedef struct sockaddr_in sockaddr_in;
int main()
{
int sock_fd;
if( sock_fd = socket(AF_INET, SOCK_STREAM, 0) < 0)
{
perror("Socket Creation error!\n");
return 1;
}
struct sockaddr_in myaddr;
memset((char*)&myaddr, 0, sizeof(myaddr));
myaddr.sin_family = AF_INET;
uint32_t myip = (127<<24)|(0<<16)|(0<<8)|1;
myaddr.sin_addr.s_addr = htonl(myip);
myaddr.sin_port = htons(1337);
int binderror = bind(sock_fd, (struct sockaddr*)&myaddr, sizeof(myaddr));
printf("bind error %d\n",binderror);
if( binderror < 0)
{
perror("Bind Error!\n");
return 1;
}
struct sockaddr_in serveraddr;
memset((char*)&serveraddr, 0, sizeof(serveraddr));
serveraddr.sin_family = AF_INET;
serveraddr.sin_port = htons(35353);
//unsigned char serverip[] = {127,0,0,1};
uint32_t serverip = (127<<24)|(0<<16)|(0<<8)|1;
serveraddr.sin_addr.s_addr = htonl(serverip);
if( connect(sock_fd, (struct sockaddr*)&serveraddr, sizeof(serveraddr)) < 0 ){
perror("Could not connect\n");
return 0;
}
}
Your problem is here -
if( sock_fd = socket(AF_INET, SOCK_STREAM, 0) < 0)
It is old precedence,
if ( a = b == c ) is like saying if ( a = ( b == c )) It is calling the function, comparing it with -1 and assign the boolean result to sock_fd
What you suppose to do is -
if( (sock_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
Related
I am new to socket programming... I tried this server side program
#define BUFLEN 512
#define MYPORT 3456
void errorp(char* msg)
{
perror(msg);
exit(1);
}
int main()
{
struct sockaddr_in server, client;
int sock;
int slen = sizeof(server);
int clen = sizeof(client);
char *recvbuf, senbuf[BUFLEN] = {'h','e','l','l','o'};
if((sock = socket(AF_INET, SOCK_DGRAM, 0) == -1))
errorp("Socket creation failed");
printf("To the client: %s, %s", senbuf, " World");
bzero(&server, sizeof(server));
server.sin_family = AF_INET;
server.sin_port = MYPORT;
server.sin_addr.s_addr = inet_addr("127.0.0.1");
if(bind(sock, (struct sockaddr*)&server, slen)==-1)
errorp("Socket Bind Failed");
if(recvfrom(sock, recvbuf, sizeof(recvbuf), 0, (struct sockaddr*) &client, &clen) == -1)
errorp("recv from error");
printf("From the client: %s", recvbuf);
if(sendto(sock, senbuf, sizeof(senbuf), 0, (struct sockaddr*) &client, sizeof(client)) == -1)
errorp("Error in sending");
printf("To the client: %s", senbuf);
close(sock);
return 0;
}
There are no compilation errors but the output is
Socket Bind Failed: Socket operation on non-socket
To the client: hello, World
Please help me figure out where the mistake is?
and help get rid of it
The error message says it all: The socket isn't a (valid) socket.
This should make you look at the code creating the socket:
if((sock = socket(AF_INET, SOCK_DGRAM, 0) == -1))
The code above 1st compares the result of the call to socket() to -1 and then assigns the result of the comparison to sock. So it's either 0 or 1. And the result of the call to socket() is lost.
The code shall look like this:
if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
as == binds tighter then =.
BTW, having used a Yoda-Conditition would have avoided such kind of "typo":
if (-1 == (sock = socket(AF_INET, SOCK_DGRAM, 0)))
Also at least clen shall be of type socklen_t as its address is passed, to have a value written into it, which will fail miserably if the size of the expected socklen_t would be different from an int (which the code shown passes).
if((sock = socket(AF_INET, SOCK_DGRAM, 0) == -1))
// \__________________________________/
You have your brackets in the wrong place. It's setting sock to a true/false value because == is "more binding" than =. It should instead be:
if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
// \_____________________________________/
which sets sock to the return value from socket() and then compares that to -1.
You also have no backing storage for recvbuf which means your recvfrom(), once it starts working, will almost certainly do something bad.
This is my tcp_server code , please correct me of i am wrong. Problem is i am not able to connect.
int tcp_server(unsigned int uiPort, unsigned int MaxConnect)
{
#define MAX_SOCKETS 1000
int isocket = -1;
struct sockaddr_in servaddr;
tcp_init();
if (MaxConnect == 0)
MaxConnect = MAX_SOCKETS;
isocket = socket(AF_INET, SOCK_STREAM, 0);
if (isocket >= 0){
memset(&servaddr, 0, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(uiPort);
if( bind(isocket, (struct sockaddr*)&servaddr, sizeof(servaddr)) == -1){
tcp_close(isocket);
isocket = -2;
}else if( listen(isocket,MaxConnect ) == -1){
tcp_close(isocket);
isocket = -3;
}
}
return isocket;
}
Where you have accepted client socket.
SOCKET cli_addr;
size_t len = sizeof(cli_addr);
newsockfd = accept(servaddr, (struct sockaddr *)&cli_addr,
&clilen);
Then on newsockfd you need to do read/write operation.
You may refer to my tutorial https://www.youtube.com/watch?v=hvcUVYC46mU. But tutorial is about WinSock.
This is my code
#include "basic.h"
#include "bp_socket.h"
int setup_tcp(char *port)
{
struct sockaddr_in server_addr;
in_port_t server_port;
int sock;
int retval; //return value
if ((server_port = atoi(port)) < 0)
{
server_port = (in_port_t)DEFAULT_PORT;
fprintf(stderr, "Error port: %d in line %d\n", (int)server_port, __LINE__);
//fprintf(stderr, "Use default port: %d\n", DEFAULT_PORT);
}
sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (sock < 0)
{
return sock;
}
retval = listen(sock, 40);
if (retval < 0)
{
return retval;
}
memset(&server_addr, 0, sizeof(struct sockaddr_in));
server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
server_addr.sin_port = htons(server_port);
server_addr.sin_family = AF_INET;
retval = bind(sock, (struct sockaddr*)&server_addr, sizeof(server_addr));
if (retval < 0)
{
perror("bind");
return retval;
}
return sock;
}
int main()
{
printf("%d\n", setup_tcp("4558"));
perror("");
return 0;
}
I debug my code, then I found bind() return -1
I google it and read man page, but I couldn't found my answer.
function setup_tcp is create socket, and bind with address.
then return a socket or errno value.
How to solve it. I had read my code for many times.
Thank you!
You should move the listen after the bind.
bind returns an error if the socket is already bound, and listen on an unbound socket automatically binds it to a random port number.
For some reason my recvfrom() function for sockets is not blocking on my server code like it is supposed to. I am making a basic UDP server to create a rolling session key system.
What am I doing wrong here? It continues on after this line (before i put the (n < 1)) and was crashing. I am pretty sure recvfrom() is supposed to stop the execution of the program until it gets something from the client...
int sockfd, portNumber;
socklen_t clilen;
char buffer[BUFFER_LENGTH];
struct sockaddr_in serv_addr, from;
int n;
// Invalid arguments
if (argc < 2)
exit(0);
else if (atoi(argv[1]) > 65535 || atoi(argv[1]) < 1)
exit(0);
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
{
printf("Error opening socket.\n");
exit(0);
}
// Taken from reference
bzero((char *) &serv_addr, sizeof(serv_addr));
portNumber = atoi(argv[1]);
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = INADDR_ANY;
serv_addr.sin_port = htons(portNumber);
if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0)
{
printf("ERROR on binding.\n");
close(sockfd);
exit(0);
}
// Get initial session key request
int fromlen = sizeof(struct sockaddr_in);
n = recvfrom(sockfd, buffer, BUFFER_LENGTH, 0, (struct sockaddr *)&from, &fromlen);
if (n < 0)
{
printf("Error in receiving.\n");
exit(1);
}
Thanks
You're trying to use a stream socket for UDP;
sockfd = socket(AF_INET, SOCK_STREAM, 0);
What you mean to do is probably;
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
Trying to do recvfrom on an unconnected stream socket will most likely return immediately with an error. Next time, you may want to check errno for a hint.
So I am really stuck here, just trying to make a simple C program that gets the content of a webpage into a buffer, but I'm having some problems; consider the following:
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD( 2, 2 );
err = WSAStartup( wVersionRequested, &wsaData );
if(err != 0)
{
printf("could not find a usable winsock.dll");
return NULL;
}
if(LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2)
{
printf("could not find a usable winsock.dll");
WSACleanup();
return NULL;
}
SOCKET sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
struct sockaddr_in sa = { 0 };
sa.sin_port = htons(port);
sa.sin_addr.s_addr = inet_addr(ip);
connect(sock, (struct sockaddr*)&sa, sizeof(sa));
The variables ip, and port, are passed through from main. as you can see here:
readsite("http://www.pagetutor.com/html_tutor/index.html", "68.71.137.60", 80);
I get the error code "10047" from executing printf("\n%d", GetLastError()); directly below the line connect(sock, (struct sockaddr*)&sa, sizeof(sa)); and this code according to microsoft means "Addresses in the specified family cannot be used with this socket" so I am completely at a lost on what to do from here.
You didn't set sin_family so it's set to AF_UNSPEC (since you 0-initialized sa). Before connecting, try:
sa.sin_family = AF_INET;