C socket programming errors - c

It's been an hour since I started looking for THE error. I just started C sockets. The program exits with code -1 after printing "Error 1 connection error". The server in online, it's a netcat server. Where did I messed up ?
#include <stdio.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <string.h>
#define HOST "127.0.0.1"
#define PORT 4444
int main(int argc, const char *argv[])
{
struct sockaddr_in addr;
int sock = 0;
int ret;
struct sockaddr_in server_addr;
char *msg = "Hello world !\n";
char inBuffer[1024] = { 0 };
if (sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP) < 0)
{
printf("Error %d socket creating.\n", sock);
exit(-1);
}
else
{
memset(&server_addr, '0', sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(PORT);
if (ret = inet_pton(AF_INET, HOST, &server_addr.sin_addr) <= 0)
{
printf("Error %d unsuported address: %d\n", ret);
exit(-2);
}
else
{
if (ret = connect(sock, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0)
{
printf("Error %d connection error\n", ret);
exit(-3);
}
else
{
send(sock, msg, strlen(msg), 0);
read(sock, inBuffer, 1024);
printf("%s\n", inBuffer);
return 0;
}
}
}
}

Due to operator precedence, the expression
sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP) < 0
is actually equal to
sock = (socket(AF_INET, SOCK_STREAM, IPPROTO_TCP) < 0)
That is, you assign the result of the comparison socket(AF_INET, SOCK_STREAM, IPPROTO_TCP) < 0 to the variable sock. The result of that comparison will always be either 0 (for false) or 1 (for true). Neither 0 nor 1 should be a valid socket.
You need to explicitly add parentheses for the assignment:
(sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0
The same needs to be done for the connect call and the comparison there.

Related

Bind error in IPv6 server

I'm trying make IPv6 server, but i have issue with socket binding.
"could not bind socket"
All code:
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <stdbool.h>
int main(int argc, char *argv[]) {
int server_port = 8877;
struct sockaddr_in6 server_address;
memset(&server_address, 0, sizeof(server_address));
server_address.sin6_family = AF_INET6;
server_address.sin6_port = htons(server_port);
server_address.sin6_addr = in6addr_any;
int sockfd;
if (sockfd = socket(AF_INET6, SOCK_STREAM, 0) < 0) {
printf("could not create listen socket\n");
return 1;
}
if (bind(sockfd, (struct sockaddr *)&server_address, sizeof(server_address)) < 0) {
printf("could not bind socket\n");
return 1;
}
int numberOfClients = 1;
if (listen(sockfd, numberOfClients) < 0) {
printf("could not open socket for listening\n");
return 1;
}
struct sockaddr_in client_address;
int client_len = 0;
char buff4[INET_ADDRSTRLEN];
while (1) {
int sock;
if ((sock =
accept(sock, (struct sockaddr *)&client_address,
0)) < 0) {
printf("could not open a socket to accept data\n");
return 1;
}
//printf("client connected with ip address: %s\n", inet_ntop(AF_INET, &(client_address.sin_addr), buff4, INET_ADDRSTRLEN));
int n = 0;
int len = 0, maxlen = 100;
char buffer[maxlen];
char *pbuffer = buffer;
printf("client connected with ip address: %s\n",
inet_ntoa(client_address.sin_addr));
while ((n = recv(sock, pbuffer, maxlen, 0)) > 0) {
pbuffer += n;
maxlen -= n;
len += n;
printf("received: '%s'\n", buffer);
// echo received content back
send(sock, buffer, len, 0);
}
close(sock);
}
close(sockfd);
return 0;
}
The problem here is your order of operations.
You have written:
if (sockfd = socket(AF_INET6, SOCK_STREAM, 0) < 0) {
You expected this to assign the return value of socket() to sockfd. But instead, it compares that return value to 0, and whether that value is less than 0 is what is actually stored in sockfd.
Before comparing, you should use an extra pair of parentheses to make explicit that you want to do the assignment and only then do the comparison:
if ((sockfd = socket(AF_INET6, SOCK_STREAM, 0)) < 0) {
Better yet, make the code more maintainable by making it more obvious what is going on, by assigning first and then comparing separately.
sockfd = socket(AF_INET6, SOCK_STREAM, 0);
if (sockfd < 0) {

socket connection failure

I am beginner in socket programming and reading Linux Network Programming book. I decided to implement client-server connection as shown in the book. Server program is run on Ubuntu 14.04 machine and client code is run from Mac machine. The server code is the following
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <string.h>
const char message[] = "hello, world\n";
int main()
{
int sock = 0;
int port = 0;
sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock == -1)
fprintf(stderr, "failed\n");
else
printf("connection is establisshed\n");
struct sockaddr_in server;
server.sin_family = AF_INET;
server.sin_addr.s_addr = htonl(INADDR_ANY );
server.sin_port = 3500;
int status = bind(sock, (struct sockaddr*) &server, sizeof(server));
if (status == 0)
printf("connection completed\n");
else
printf("problem is encountered\n");
status = listen(sock, 5);
if (status == 0)
printf("app is ready to work\n");
else
{
printf("connection is failed\n");
return 0;
}
while (1)
{
struct sockaddr_in client = { 0 };
int sclient = 0;
int len = sizeof(client);
int childSocket = accept(sock, (struct sockaddr*) &client, &len);
if (childSocket == -1)
{
printf("cannot accept connection\n");
close(sock);
break;
}
write(childSocket, message, strlen(message));
close(childSocket);
}
return 0;
}
As for client side i wrote the following code
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <stdlib.h>
#include <unistd.h>
#include <arpa/inet.h>
int main(int argc, char* argv[])
{
int sock = 0;
int port = 0;
struct sockaddr_in servaddr;
sock = socket(AF_INET, SOCK_STREAM, 0);
int status = 0;
char buffer[256] = "";
if (sock == -1)
{
printf("could not establish connection\n");
exit(1);
}
port = 3500;
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = inet_addr(argv[1]);
servaddr.sin_port = htons(port);
status = connect(sock, (struct sockaddr*) &servaddr, sizeof(servaddr));
if (status == 0)
printf("connection is established successfully\n");
else
{
printf("could not run the app\n");
exit(1);
}
status = read(sock, buffer, sizeof(buffer));
if (status > 0)
printf("%d: %s", status, buffer);
close(sock);
return 0;
}
To get IP address of client machine I run ifconfig from terminal an get inet_addr 192.168.1.165 value. Now when I pass that address string as command line argument I get message that app is not running message. There is problem with address that I got, as I understand. So what is the problem?
Thanks in advance
Most probably the server does not listen on the port you are assuming, that is 3500.
To fix this, change this line:
server.sin_port=3500
to be
server.sin_port = htons(3500);
(To monitor which process is listing on which address:port you might like to use the netstat command line tool. In your case probably using the options -a -p -n )
Also on recent systems accept() expects a pointer to socklen_t as last parameter, so change this
int len=sizeof(client);
to be
socklen_t len = sizeof client; /* sizeof is an operator, not a function¨*/

C TCP/IP Server Bind Error -- Socket operation on non-socket [duplicate]

This question already has an answer here:
Connect: Socket operation on non-socket
(1 answer)
Closed 7 years ago.
when I run the following program my program gets up to the bind function and fails leaving me with the error "Socket operation on non-socket". Im unsure what is happening. I compile with "gcc a3server.c -g -o server" and there are no compilation errors.
#include <stdio.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
int main(int argc, char *argv[])
{
if (argc != 2)
{
printf("Error. Please enter the right amount of arguments (2)");
exit(1);
}
int sock, port, clientlen, connection, readfd, writefd;
char buffer[255];
struct sockaddr_in server, clientaddr;
if (sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP) < 0)
{
printf("Socket was not made.");
exit(1);
}
//bzero((char *) &server, sizeof(server));
port = atoi(argv[1]);
server.sin_family = AF_INET;
server.sin_addr.s_addr = INADDR_ANY;
server.sin_port = htons(port);
int bindfd = bind(sock, (struct sockaddr *) &server, sizeof(server));
if (bindfd < 0)
{
perror("Could not bind socket to address: ");
exit(1);
}
listen(sock, 5);
clientlen = sizeof(clientaddr);
if (connection = accept(sock, (struct sockaddr *) &clientaddr, &clientlen) < 0)
{
printf("Could not accept connection");
exit(1);
}
if (readfd = read(connection, buffer, 255) < 0)
{
printf("Could not read from socket");
exit(1);
}
printf("!---THIS IS A TEST---! \n BUFFER: %s", buffer);
if (writefd = write(connection, buffer, 255) < 0)
{
printf("Could not write to socket");
exit(1);
}
return 0;
}
Line
if (sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP) < 0)
should be
if ( (sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)

connect() function taking too long

When I type in to the terminal:
echo "GET /" | ./<executable name> www.google.com <port number, usually 80>
the terminal just sits there like it's waiting for input or it's stuck in an infinite loop. What is happening is that connection is taking too long I think.
/*Creating socket*/
int sock = socket(AF_INET,SOCK_STREAM, IPPROTO_TCP);
if (sock < 0) {
printf("error creating socket\n");
exit(1);
}
printf("1\n");
/*Establish connection to the echo server*/
int r = connect(sock, addrList->ai_addr, addrList->ai_addrlen);
printf("1.5\n");
if (r < 0) {
perror("Connection failed\n");
exit(1);
}
printf("2\n");
Here, the 1 prints out, but the 1.5 right after the connect doesn't print out and the terminal just sits.
This problem didn't happen before and I used to get the page's source code back instantly. But now this problem is occurring.
It started occurring after I typed in to the terminal: netstat -an -A inet | grep :2525
so this may have had an effect.
Here is the entire code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
int main(int argc, char *argv[]) {
if (argc != 3) {
printf("Invalid arguments\n");
exit(1);
}
char *serverIP = argv[1]; /*Server hostname*/
char *portNumber = argv[2]; /*Port Number*/
void *numericAddress;
char addrBuffer[INET6_ADDRSTRLEN];
in_port_t port;
char buffer_stdin[65535];
char buffer_stdout[65535];
int bytes_read = 0;
int bytes_written = 0;
/*getting integral number of string representation of port number*/
in_port_t servPort = atoi(argv[2]);
/*------------------get binary number of hostname-----------------*/
struct addrinfo addrCriteria;
memset(&addrCriteria, 0, sizeof(addrCriteria));
addrCriteria.ai_family = AF_INET;
addrCriteria.ai_socktype = SOCK_STREAM;
addrCriteria.ai_protocol = IPPROTO_TCP;
struct addrinfo *addrList;
int rtnVal = getaddrinfo(serverIP, portNumber, &addrCriteria, &addrList);
if (rtnVal != 0) {
printf("getaddrinfo() failed\n");
exit(1);
}
numericAddress = &((struct sockaddr_in *) (addrList->ai_addr))->sin_addr;
/*Converting port to binary*/
((struct sockaddr_in *)(addrList->ai_addr))->sin_port = htonl(servPort);
/*----------------------------------------------------------------*/
inet_ntop(addrList->ai_addr->sa_family, numericAddress, addrBuffer, sizeof(addrBuffer));
printf("IP ADDRESS: %s\n", addrBuffer);
/*Creating socket*/
int sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (sock < 0) {
printf("error creating socket\n");
exit(1);
}
/*printf("1\n");*/
/*Establish connection to the echo server*/
int r = connect(sock, addrList->ai_addr, addrList->ai_addrlen);
printf("%d\n", r);
if (r < 0) {
perror("Connection failed\n");
exit(1);
}
printf("2\n");
/*Reading from stdin and writing to socket until stdin ends
bytes_read = read(0, buffer_stdin, sizeof(buffer_stdin));
write(sock, buffer_stdin, bytes_read);*/
while ((bytes_read = read(0, buffer_stdin, sizeof(buffer_stdin)-1)) > 0) {
write(sock, buffer_stdin, bytes_read);
}
/*Shutting down write end of socket*/
int r_shutdown = shutdown(sock, SHUT_WR);
if (r_shutdown < 0) {
printf("Shutting down write end of socket failed\n");
exit(1);
}
/*Reading from socket and writing to stdout until socket ends*/
while ((bytes_read = read(sock, buffer_stdout, sizeof(buffer_stdout)-1)) > 0) {
write(1, buffer_stdout, bytes_read);
}
close(sock);
exit(0);
}
The correct way to do it is :
struct sockaddr_in address;
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if(sockfd!=-1)
{
perror("socket :");
printf("sockfd = %d\n", sockfd);
}
else
{
perror("socket");
exit(EXIT_FAILURE);
}
address.sin_family = AF_INET;
address.sin_addr.s_addr = inet_addr("127.0.0.1");
address.sin_port = htons(9734);
len = sizeof(struct sockaddr_in);
result = connect(sockfd, (struct sockaddr *)&address, len);
Nvm I figured it out.
Apparently I had to take into account big endian vs little endian, and so in this line:
((struct sockaddr_in *)(addrList->ai_addr))->sin_port = htonl(servPort);
the htonl should've been htons, so:
((struct sockaddr_in *)(addrList->ai_addr))->sin_port = htons(servPort);

Socket program gives "Transport endpoint is already connected" error

I am trying to create a very simple client-server chat program, where two programs can communicate with each other. However, the accept function is giving me the error "invalid argument". I am pasting the code here:
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>
#include <fcntl.h>
#include <stdlib.h>
#include <errno.h>
int main()
{
struct sockaddr_in myaddr;
struct sockaddr_in otheraddr;
int sockid;
int bindid;
int recvsockid;
int clientlen;
int connectid;
char send_msg[100] = "Program 1", recv_msg[100];
int recvid, sendid;
int myport_id = 4550;
int otherport_id = 4560;
sockid = socket(AF_INET, SOCK_STREAM, 0);
//fcntl(sockid, F_SETFL, O_NONBLOCK);
if (sockid < 0)
{
printf("\nCould not create socket");
}
bzero((char*)&myaddr, sizeof(struct sockaddr_in));
myaddr.sin_family = AF_INET;
myaddr.sin_addr.s_addr = inet_addr("127.0.0.1");
myaddr.sin_port = htons(myport_id);
bzero((char*)&otheraddr, sizeof(struct sockaddr_in));
otheraddr.sin_family = AF_INET;
otheraddr.sin_addr.s_addr = inet_addr("127.0.0.1");
otheraddr.sin_port = htons(otherport_id);
bindid = bind(sockid, (struct sockaddr*)&myaddr, sizeof(struct sockaddr_in));
if(bindid < 0)
printf("bind error \n");
listen(bindid, 5);
do
{
connectid = connect(sockid, (struct sockaddr*)&otheraddr, sizeof(struct sockaddr_in));
if (connectid < 0 && !(errno == EINPROGRESS))
{
//printf("%s", strerror(errno));
perror("connect");
exit(1);
}
recvsockid = accept(sockid, (struct sockaddr*)&myaddr, &clientlen);
if (recvsockid < 0 && !(errno == EINPROGRESS || errno == EAGAIN))
{
perror("accept");
exit(1);
}
} while (connectid < 0 && recvsockid < 0);
do
{
gets(send_msg);
sendid = sendto(sockid, send_msg, 100, 0, (struct sockaddr*)&otheraddr, sizeof(struct sockaddr_in));
fprintf(stderr, "%d", sendid);
if(sendid < 0)
printf("error3\n");
recvid = recvfrom(recvsockid, recv_msg, 100, 0, (struct sockaddr*)&myaddr, &clientlen);
if (recvid < 0)
{
printf("\nError in receive");
break;
}
} while (1);
return 0;
}
I will be grateful if someone could tell me why I am getting this error, and how to correct it.
Thanks a lot.
Your problem is that you are trying to connect and to listen on the same socket sockid. I'm pretty sure you meant bindid for listening.
Edit 0:
Since you are creating both sides of the TCP connection in the same program, you need two socket descriptors, i.e. two calls to socket(2) in the setup code, one for connecting and one for accepting client connections.
recvsockid = accept(sockid, (struct sockaddr*)&myaddr, &clientlen);
You have not initialized clientlen, if you look at the documentation for accept():
address_len
Points to a socklen_t structure which on input specifies the length of the supplied sockaddr structure, and on output specifies
the length of the stored address.
So, set it to the length of myaddr prior to calling accept():
client_len = sizeof myaddr;
recvsockid = accept(sockid, (struct sockaddr*)&myaddr, &clientlen);

Resources