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.
Related
I am fairly new to socket programming. I saw a tutorial and tried implementing the programs in my Linux machine. The codes are :
CLIENT :
int main() {
char buf[256] = "In client";
// create the socket
int sock;
sock = socket(AF_INET, SOCK_STREAM, 0);
//setup an address
struct sockaddr_in server_address;
server_address.sin_family = AF_INET;
server_address.sin_addr.s_addr = INADDR_ANY;
server_address.sin_port = htons(9002);
int status = connect(sock, (struct sockaddr *) &server_address, sizeof(server_address));
if(status == -1)
{
printf("There Was an error!");
}
recv(sock, buf, sizeof(buf), 0);
printf("\n %s \n", buf);
close(sock);
return 0;
}
SERVER:
int main() {
char server_message[256] = "You have reached the server!";
// create the server socket
int server_socket;
server_socket = socket(AF_INET, SOCK_STREAM, 0);
// define the server address
struct sockaddr_in server_address;
server_address.sin_family = AF_INET;
server_address.sin_port = htons(9002);
server_address.sin_addr.s_addr = INADDR_ANY;
// bind the socket to our specified IP and port
bind(server_socket, (struct sockaddr*) &server_address, sizeof(server_address));
listen(server_socket, 5);
int client_socket;
client_socket = accept(server_socket, NULL, NULL);
// send the message
send(client_socket, server_message, sizeof(server_message), 0);
// close the socket
close(server_socket);
return 0;
}
The code is self-explanatory. When I run the server and then the client, for the first time, it works. But when I do it again, just after the previous one, the Client gives the message - There Was an error!, that means the connection is not happening.
Can anyone help why is this occurring?
Thanks in advance!
You should be checking for errors for all system calls in your server. I'm guessing that your bind is failing, because the port is "already in use". The reason for this is that the connection from the previous instance of the server lingers for a while in the operating system's connection table.
You want to use setsockopt with SO_REUSEADDR to avoid the bind failure. Specifically, add this prior to the bind call.
int reuse = 1;
if (setsockopt(server_socket, SOL_SOCKET, SO_REUSEADDR, (const char*)&reuse, sizeof(reuse)) < 0)
perror("setsockopt(SO_REUSEADDR) failed");
(And do check errors. Makes debugging these kinds of things much easier if you know when something fails. Also, use perror or strerror(errno) in order to find out exactly why it failed -- not just that it failed.)
Check out my whole code here and see how it runs.
This is the server
int main(){
SOCKET s, newsocket;
struct sockaddr_in server, client;
int receiving;
char clientMessage[2000], *message;
if((s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET){
printf("socker error at %d", GetLastError());
}else{
puts("socket created");
}
server.sin_addr.s_addr = inet_addr("127.0.0.1");
server.sin_family = AF_INET;
server.sin_port = htons(8080);
if(bind(s, (struct sockaddr*)&server, sizeof(server)) < 0){
printf("err at binding %d", GetLastError());
}else{
puts("binded.");
}
listen(s, 3);
puts("listening to connections...");
int c = sizeof(struct sockaddr_in);
while((newsocket = accept(s, (struct sockaddr*)&client, &c)) != INVALID_SOCKET){
puts("connection accepted");
//send
message="hello client";
send(newsocket, message, strlen(message), 0);
recv(newsocket, clientMessage, 50, 0);
puts(clientMessage);
}
puts("waiting for a machine");
if(newsocket == INVALID_SOCKET){
printf("newsocket invalid at %d", GetLastError());
}
getchar();
closesocket(s);
WSACleanup();
}
This is the client
int main(){
SOCKET s;
struct sockaddr_in server;
if((s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET){
printf("socket error At %d", GetLastError());
}else{
puts("socket initialised");
}
server.sin_port = htons(8080);
server.sin_family = AF_INET;
server.sin_addr.s_addr = inet_addr("176.40.201.72");
printf("server values are defined.. \n");
printf("connecting..\n");
if(connect(s, (struct sockaddr*)&server, sizeof(server)) < 0){
printf("connection error %d" , GetLastError());
}else{
puts("connected");
}
return 0;
}
This is supposed to bind a socket to a port on the local host and accept TCP connections. When I run it, I get my "Bind error" message. I used this tutorial (see the "Accept connection" section), and the only significant difference I can see between that and my code is the position of the server address and port member initializations, which shouldn't matter, as long as they come before the bind() call?
I added a new rule in Windows Firewall (on Windows 7) to allow TCP connections from this executable, on port 8888, but that doesn't seem to help.
#include <stdio.h>
#include <winsock2.h>
#pragma comment(lib, "ws2_32.lib")
int main(int argc, char *argv[])
{
WSADATA wsa;
SOCKET s, new_socket;
struct sockaddr_in server, client;
int c;
printf("\nInitializing WinSock...");
if (WSAStartup(MAKEWORD(2,2),&wsa) != 0)
{
printf("Failed. Error code: %d\n\n", WSAGetLastError());
exit(1);
}
printf("\nInitialized.");
server.sin_addr.s_addr = INADDR_ANY;
server.sin_port = htons(8888);
server.sin_family = AF_INET;
if (s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP) == INVALID_SOCKET)
{
printf("\nCould not create socket: %d", WSAGetLastError());
exit(1);
}
printf("\nSocket created.\n");
if (bind(s, (struct sockaddr *)&server, sizeof(server)) == SOCKET_ERROR)
{
printf("\nBind error.\n\n");
exit(1);
}
printf("\nSocket bound to port 8888.\n\n");
listen(s, 3);
printf("\nWaiting for incoming connections...");
c = sizeof(struct sockaddr_in);
new_socket = accept(s, (struct sockaddr *)&client, &c);
if (new_socket == INVALID_SOCKET)
{
printf("\nAccept failed.\n\n");
exit(1);
}
printf("\nConnection accepted.");
closesocket(s);
WSACleanup();
return 0;
}
This statement:
if (s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP) == INVALID_SOCKET)
Needs an additional set of parenthesis around the assignment:
if ((s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET)
The == operator has a higher precedence then the = operator (see Operator Precedence), so your original statement implicitly acts as if you had written it like this instead:
if (s = (socket(AF_INET, SOCK_STREAM, IPPROTO_TCP) == INVALID_SOCKET))
If socket() succeeds, the comparison would evaluate to false, which then assigns 0 to s (since SOCKET is just an alias for UINT_PTR, assigning a boolean value to a SOCKET variable is allowed), and then bind() would fail with the WSAENOTSOCK error (if socket() fails, the comparison would evaluate to true, which would assign 1 to s, then the if would evaluate as true and your process would exit).
Personally, I dislike code that does assignments and comparisons in the same statement. This would be clearer and safer:
s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (s == INVALID_SOCKET)
Also, don't forget to call closesocket() on new_socket after accept() succeeds.
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)
I am getting an error "Invalid argument" when i call the accept() function on the server side of a client-server application. I don't get what is wrong and if you see what is wrong let me know please. Thanks.
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
int main(int argc, char* argv[])
{
int sockfd, newsockfd, portno, len;
struct sockaddr_in server, client;
if(argc < 2){
perror("Add more arguments");
}
sockfd = socket(AF_UNIX,SOCK_STREAM,0);
if(sockfd < 0){
perror("Error at socket()");
}
printf("Socketfd: %d\n",sockfd);
bzero((char *)&server, sizeof(server));
portno = atoi(argv[1]);
server.sin_family = AF_UNIX;
server.sin_addr.s_addr = INADDR_ANY;
server.sin_port = htons(portno);
if(bind (sockfd, (struct sockaddr *)&server, sizeof(server)) <0){
perror("Error at bind ()-server");
}
listen(sockfd,5);
int readval;
char buffer[256];
for(;;){
len = sizeof(client);
newsockfd = accept (sockfd, (struct sockaddr *)&server,&len);
if (newsockfd == -1){
perror("Erroare at accept()");
}
else do{
readval = (sockfd,buffer,sizeof(buffer));
if (readval < 0 ){
perror("Error at reading()");
}
else if (readval == 0){
printf("End conection");
}
else{
printf("Mesage is: %s\n", buffer);
}
}while (readval > 0);
close(newsockfd);
}
return 0;
}
You have to use sockaddr_un instead of sockaddr_in for Unix domain sockets OR substitute AF_UNIX with AF_INET.
Plus, check the return of listen.
Plus change this line
readval = (sockfd,buffer,sizeof(buffer));
with
readval = read(newsockfd,buffer,sizeof(buffer));
because data is going to be sent through the newly created socket and not on the listening one
Plus, as mentioned by #trojanfoe, subst the server with the client structure into the accept() call
This line:
newsockfd = accept (sockfd, (struct sockaddr *)&server, &len);
Should be:
newsockfd = accept (sockfd, (struct sockaddr *)&client, &len);
From the manpage:
The argument addr is a pointer to a sockaddr structure. This structure
is filled in with the address of the peer socket, as known to the
communications layer. The exact format of the address returned addr is
determined by the socket's address family (see socket(2) and the
respective protocol man pages). When addr is NULL, nothing is filled
in; in this case, addrlen is not used, and should also be NULL.
Also check the return value from listen().
I ran into a similar issue before and it was due to not having the read function in a loop. Here is an example I did before.
while (1) {
new_sockfd = accept(sockfd, (struct sockaddr *) &client_addr,
&sin_size);
if (new_sockfd == -1)
perror("accepting connection");
printf("server: got connection from %s port %d\n",
inet_ntoa(client_addr.sin_addr),
ntohs(client_addr.sin_port));
recv_length = recv(new_sockfd, &buffer, DATA, 0);
while (recv_length > 0) {
printf("RECV: %d bytes\n", recv_length);
dump(buffer, recv_length);
recv_length = recv(new_sockfd, &buffer, DATA, 0);
}
close(new_sockfd);
}
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.