I am trying to compile this C program but I am getting this message
warning: passing 'int *' to parameter of type 'socklen_t *'
(aka 'unsigned int *') converts between pointers to integer types with
different sign [-Wpointer-sign]
if ((new_s = accept(s, (struct sockaddr *) &sin, &addr_len)) < 0) {
^~~~~~~~~
someone could help me?
#include<string.h>
#include<stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <fcntl.h> // for open
#include <unistd.h> // for close
#define SERVER_PORT 5432
#define MAX_PENDING 5
#define MAX_LINE 256
int main()
{
struct sockaddr_in sin;
char buf[MAX_LINE];
int buf_len, addr_len;
int s, new_s;
/* build address data structure */
bzero((char *)&sin, sizeof(sin));
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = INADDR_ANY;
sin.sin_port = htons(SERVER_PORT);
/* setup passive open */
if ((s = socket(PF_INET, SOCK_STREAM, 0)) < 0) {
perror("simplex-talk: socket");
exit(1);
}
if ((bind(s, (struct sockaddr *)&sin, sizeof(sin))) < 0) {
perror("simplex-talk: bind");
exit(1);
}
listen(s, MAX_PENDING);
/* wait for connection, then receive and print text */
while(1) {
if ((new_s = accept(s, (struct sockaddr *) &sin, &addr_len)) < 0) {
perror("simplex-talk: accept");
exit(1);
}
while (buf_len == recv(new_s, buf, sizeof(buf), 0))
fputs(buf, stdout);
close(new_s);
}
}
As the error message states, you're passing an int * argument to accept for the last argument when the function expects a socklen_t * for this argument.
So change the type of addr_len to socklen_t.
Related
I'm trying to send messages to a server, but when I connect, the server immediately fails receiving the message. It seems that the server "does not wait" for the user to type the message. The server is supposed to remain in that while loop, forever waiting for clients and printing their messages.
I have no idea what's wrong.
Server code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <dirent.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <pthread.h>
#define PORT 4000
#define WORD_SIZE 256
#define USER_SOCKETS 2
#define MAX_USERS 10
int receiveMessage(int socket, char message[])
{
int bytesReceived;
while (1)
{
bytesReceived = recv(socket, message, WORD_SIZE, 0);
if (bytesReceived < 0)
return -1;
if (bytesReceived == 0)
return 0;
}
}
int main(int argc, char *argv[])
{
int serverSockfd;
socklen_t clilen;
struct sockaddr_in serv_addr, cli_addr;
if ((serverSockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
printf("Error creating the socket.\n");
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(PORT);
serv_addr.sin_addr.s_addr = INADDR_ANY;
bzero(&(serv_addr.sin_zero), 8);
if (bind(serverSockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0)
{
printf("Error binding the socket..\n");
return -1;
}
if (listen(serverSockfd, 5) < 0)
{
printf("Error on listening.\n");
return -1;
}
int newSockfd;
while (1)
{
if (newSockfd = accept(serverSockfd, (struct sockaddr *)&cli_addr, &clilen) < 0)
{
printf("Error on accept a new client.\n");
continue;
}
char username[WORD_SIZE];
if (receiveMessage(newSockfd, username) < 0)
{
printf("Error receiving message.\n");
close(newSockfd);
}
printf("Message: %s\n", username);
close(newSockfd);
}
return 0;
}
Client code:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#define PORT 4000
int main(int argc, char * argv[]) {
int sockfd, n;
struct sockaddr_in serv_addr;
struct hostent * server;
char buffer[256];
if (argc < 2) {
fprintf(stderr, "usage %s hostname\n", argv[0]);
exit(0);
}
server = gethostbyname(argv[1]);
if (server == NULL) {
fprintf(stderr, "ERROR, no such host\n");
exit(0);
}
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
printf("ERROR opening socket\n");
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(PORT);
serv_addr.sin_addr = * ((struct in_addr * ) server -> h_addr);
bzero( & (serv_addr.sin_zero), 8);
if (connect(sockfd, (struct sockaddr * ) & serv_addr, sizeof(serv_addr)) < 0)
printf("ERROR connecting\n");
printf("Enter the message: ");
bzero(buffer, 256);
fgets(buffer, 256, stdin);
/* write in the socket */
n = write(sockfd, buffer, strlen(buffer));
if (n < 0)
printf("ERROR writing to socket\n");
bzero(buffer, 256);
printf("%s\n", buffer);
close(sockfd);
return 0;
}
The line:
if (newSockfd = accept(serverSockfd, (struct sockaddr *)&cli_addr, &clilen) < 0)
will set newSockfd to 0 if accept() succeeds, rather than to the descriptor of the socket. This is because < has a higher precedence than =, so the compiler behaves as-if you had written this:
if (newSockfd = (accept(serverSockfd, (struct sockaddr *)&cli_addr, &clilen) < 0))
You need to write this instead:
if ((newSockfd = accept(serverSockfd, (struct sockaddr *)&cli_addr, &clilen)) < 0)
As the title says, I am creating a server/client connection. The server will allow multiple clients while the clients can communicate with the server. I have both server and client files. I am not sure where I am going wrong.
I execute each line in cygwin
gcc server.c -o server lpthread
crashes :(
gcc client.c -o client
./client localhost 8080
Server.c
#include <stdio.h>
#include <stdlib.h> // for IOs
#include <string.h>
#include <unistd.h>
#include <sys/types.h> // for system calls
#include <sys/socket.h> // for sockets
#include <netinet/in.h> // for internet
#include <stdbool.h>
#include <pthread.h> // for thread;
/* a function to print out error message and then abort */
void error(const char *msg) {
perror(msg);
exit(1);
}
void *threadFunct(int mySockfd) {
char buffer2[256];
bool exitFlag = false;
int read_writeLen;
while(!exitFlag) {
bzero(buffer2, 256);
read_writeLen = read(mySockfd, buffer2, 255);
if (read_writeLen < 0)
printf("ERROR reading from the client socket\n");
if(strcmp(buffer2,"EXIT\n")==0) {
printf("Now socket %d will be close\n", mySockfd);
close(mySockfd);
pthread_exit(mySockfd); // terminate the calling thread
} else {
printf("The message read from socket %d :%s\n ",mySockfd,buffer2);
read_writeLen = write(mySockfd,"I got Your Message" , 18);
if (read_writeLen < 0)
printf("Unable to write to socket\n");
}
}
close(mySockfd);
return NULL;
}
int main(int argc, char *argv[]) {
int sockfd, newsockfd, portno;
socklen_t clilen;
char buffer[256];
struct sockaddr_in serv_addr, cli_addr;
int charRead_Written;
if(argc <2) {
fprintf(stderr, "ERROR, no port provided\n");
exit(1);
}
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if(sockfd < 0)
error("ERROR Opening 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 on binding");
while(true) {
pthread_t threadId;
listen(sockfd,10);
clilen = sizeof(cli_addr);
newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen);
if(newsockfd<0)
error("ERROR on accept");
pthread_create(&threadId,NULL,threadFunct,newsockfd);
}
close(sockfd);
return 0;
}
Client.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <string.h>
#include <stdbool.h>
void error(const char *msg) {
perror(msg);
exit(0);
}
int main(int argc, char *argv[]) {
int sockfd, portno, n;
struct sockaddr_in serv_addr;
struct hostent *server;
bool running = false; // Keep running until the user types EXIT
// gcc client.c -o client
// ./client localhost port
char buffer[256];
if (argc <3) {
fprintf(stderr, "usage %s hostname port\n", argv[0]);
exit(0);
}
portno = atoi(argv[2]);
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if(sockfd <0)
error("ERROR opening socket");
server = 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 Connecting");
while(!running) {
printf("Please Enter The message: ");
bzero(buffer, 256);
fgets(buffer, 255, stdin);
n = write(sockfd, buffer, strlen(buffer));
if(n<0)
error("ERROR writing from socket");
if(strcmp(buffer, "EXIT\n")== 0)
{
running = true;
break;
}
bzero(buffer,256);
n = read(sockfd, buffer,255);
if(n < 0)
printf("ERROR reading from socket");
printf("%s\n", buffer);
}
close(sockfd);
return 0;
}
The client.c file compiles and works fine. The server.c file does not compile and not sure how to solve the issues. Posted compile results below for server.c.
server.c: In function ‘threadFunct’:
server.c:39:17: warning: passing argument 1 of ‘pthread_exit’ makes pointer from integer without a cast [-Wint-conversion]
pthread_exit(mySockfd); // terminate the calling thread
^~~~~~~~
In file included from server.c:18:0:
/usr/include/pthread.h:150:6: note: expected ‘void *’ but argument is of type ‘int’
void pthread_exit (void *) __attribute__ ((__noreturn__));
^~~~~~~~~~~~
server.c: In function ‘main’:
server.c:85:36: warning: passing argument 3 of ‘pthread_create’ from incompatible pointer type [-Wincompatible-pointer-types]
pthread_create(&threadId,NULL,threadFunct,newsockfd);
^~~~~~~~~~~
In file included from server.c:18:0:
/usr/include/pthread.h:146:5: note: expected ‘void * (*)(void *)’ but argument is of type ‘void * (*)(int)’
int pthread_create (pthread_t *, const pthread_attr_t *,
^~~~~~~~~~~~~~
server.c:85:48: warning: passing argument 4 of ‘pthread_create’ makes pointer from integer without a cast [-Wint-conversion]
pthread_create(&threadId,NULL,threadFunct,newsockfd);
^~~~~~~~~
In file included from server.c:18:0:
/usr/include/pthread.h:146:5: note: expected ‘void *’ but argument is of type ‘int’
int pthread_create (pthread_t *, const pthread_attr_t *,
Instead of this:
pthread_exit(mySockfd); // terminate the calling thread
This:
pthread_exit(NULL); // terminate the calling thread
Instead of this:
void *threadFunct(int mySockfd)
This:
struct MyArgs
{
int mySockfd;
};
void *threadFunct(void* args)
{
int mySockfd = ((struct MyArgs*)args)->mySockfd;
Then create the thread as follows:
struct MyArgs* args = (struct MyArgs*)malloc(sizeof(struct MyArgs));
args->mySockfd = mySockfd;
pthread_create(&threadId,NULL,threadFunct,(void*)args);
You're on your own to properly invoke free on that allocate structure after the thread has exited or is about to exit.
I'm making a simple UDP daytime client. I'm getting this when I try to compile. I've tried casting these to see if they would work but that doesn't lead anywhere. How should I go about entering these parameters with what I have (or am I missing something that should be put there)?
UDPday2.cpp:57:86: error: invalid conversion from ‘int*’ to ‘socklen_t* {aka unsigned int*}’ [-fpermissive]
n = recvfrom(sockfd, buf,(int) sizeof(buf), 0, (sockaddr*)&serveraddr, &serverlen);
^
In file included from UDPday2.cpp:6:0:
/usr/include/i386-linux-gnu/sys/socket.h:174:16: error: initializing argument 6 of ‘ssize_t recvfrom(int, void*, size_t, int, sockaddr*, socklen_t*)’ [-fpermissive]
extern ssize_t recvfrom (int __fd, void *__restrict __buf, size_t __n,
#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 <netdb.h>
#define BUFSIZE 1024
void error(char *msg) {
perror(msg);
exit(0);
}
int main(int argc, char **argv) {
int sockfd, portno, n;
int serverlen;
struct sockaddr_in serveraddr;
struct hostent *server;
char *hostname;
char buf[BUFSIZE];
portno = 13;
if(argc == 1)
hostname = "localhost";
else
hostname = argv[1];
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if (sockfd < 0)
error("socket");
server = gethostbyname(hostname);
if (server == NULL) {
fprintf(stderr," no host %s\n", hostname);
exit(0);
}
bzero((char *) &serveraddr, 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);
n = sendto(sockfd, buf,(int)strlen(buf)+1, 0,(sockaddr*)&serveraddr , serverlen);
if (n < 0)
error("ERROR send");
n = recvfrom(sockfd, buf,(int) sizeof(buf), 0, (sockaddr*)&serveraddr, &serverlen);
if (n < 0)
error("ERROR recvfrom");
printf(" %s", buf);
return 0;
}
serverlen needs to be declared as unsigned, or as a socklen_t. You should have been able to deduce that from the error message.
I would like to make program so that, when client disconnected, the server will back ready to accept a new request from client. Here is the code
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <time.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#define MAXLINE 100
#define LISTENQ 10
int main()
{
int tmp, listenfd, connfd;
int sin_size;
struct sockaddr_in servaddr, cliaddr;
char buff[MAXLINE];
time_t ticks;
while(true)
{
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = INADDR_ANY;
servaddr.sin_port = htons(13);
memset(&(servaddr.sin_zero),'\0',8);
listenfd = socket(AF_INET, SOCK_STREAM, 0);
if(listenfd == -1){
perror("error socket");
exit(1);
}
tmp=bind(listenfd, (struct sockaddr *)&servaddr, sizeof(struct sockaddr));
if(tmp == -1){
perror("error bind..");
exit(1);
}
tmp=listen(listenfd, LISTENQ);
if(tmp == -1){
perror("error listen");
exit(1);
}
sin_size = sizeof(struct sockaddr_in);
connfd=accept(listenfd,(struct sockaddr *)&cliaddr, &sin_size);
if(connfd == -1){
perror("error accept");
exit(1);
}
ticks = time(NULL);
snprintf(buff,sizeof(buff),"Now Time: %.24s\r\n", ctime(&ticks));
write(connfd, buff, strlen(buff));
close(connfd);
close(listenfd);
}
}
I found a problem on this part
tmp=bind(listenfd, (struct sockaddr *)&servaddr, sizeof(struct sockaddr));
error: invalid conversion from 'int*' to 'socklen_t* {aka unsigned int*}' [-fpermissive]
connfd=accept(listenfd,(struct sockaddr *)&cliaddr, &sin_size);
error: initializing argument 3 of 'int accept(int, sockaddr*, socklen_t*)' [-fpermissive]
What should I do with those problem? Didn't the pointer right?
You need to use
socklen_t sin_size;
Chnage your declaration
socklen_t sin_size;
This solves your issue.
you can also Try this as last resort but above change would works fine for you.
Modify this statement
connfd=accept(listenfd,(struct sockaddr *)&cliaddr,(socklen_t * ) &sin_size);
See man accept
After seeing #alk comment i am adding this part from comment.
Especially when casting pointers, it might just cast away an compile-time error but very well might crash when running as the sizes of what the program expects when Dereferencing the pointer differs from reality.
Use while(1) instead of while(true) and use a C-compiler instead of a C++-compiler.
The errors come from compiling the source code with a C++compiler. If you use a C-Compiler your code does not produce the mentioned errors, except that now true is not defined.
Correct answer, need to run on root-access user
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <time.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdbool.h>
#define MAXLINE 100
#define LISTENQ 10
int main()
{
int tmp, listenfd, connfd;
socklen_t sin_size;
struct sockaddr_in servaddr, cliaddr;
char buff[MAXLINE];
time_t ticks;
while(true)
{
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = INADDR_ANY;
servaddr.sin_port = htons(13);
memset(&(servaddr.sin_zero),'\0',8);
listenfd = socket(AF_INET, SOCK_STREAM, 0);
if(listenfd == -1){
perror("error socket");
exit(1);
}
tmp=bind(listenfd, (struct sockaddr *)&servaddr, sizeof(struct sockaddr));
if(tmp == -1){
perror("error bind..");
exit(1);
}
tmp=listen(listenfd, LISTENQ);
if(tmp == -1){
perror("error listen");
exit(1);
}
sin_size = sizeof(struct sockaddr_in);
connfd=accept(listenfd,(struct sockaddr *)&cliaddr, &sin_size);
if(connfd == -1){
perror("error accept");
exit(1);
}
ticks = time(NULL);
snprintf(buff,sizeof(buff),"Sekarang pukul: %.24s\r\n", ctime(&ticks));
write(connfd, buff, strlen(buff));
close(connfd);
close(listenfd);
}
}
I am trying to implement a tcp client and tcp server. I am able to establish the connection but when I send a message from the client, the server doesn't receive it and yes I did look at the previous posts and there were alot of similar problems. I did follow them but I am still getting the same error. The error i am getting is from server side:
recv: Socket operation on non-socket
Here is my code. If you can please let me know what I am doing wrong, I would really appreciate it. I think there is a problem in my server implementation.
Server:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#define PORT 3490
#define BACKLOG 10
int main()
{
struct sockaddr_in server;
struct sockaddr_in dest;
int status,socket_fd, client_fd,num;
socklen_t size;
char buffer[10240];
memset(buffer,0,sizeof(buffer));
int yes = 1;
if ((socket_fd = socket(AF_INET, SOCK_STREAM, 0))== -1) {
fprintf(stderr, "Socket failure!!\n");
exit(1);
}
if (setsockopt(socket_fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1) {
perror("setsockopt");
exit(1);
}
memset(&server, 0, sizeof(server));
memset(&dest,0,sizeof(dest));
server.sin_family = AF_INET;
server.sin_port = htons(PORT);
server.sin_addr.s_addr = INADDR_ANY;
if ((bind(socket_fd, (struct sockaddr *)&server, sizeof(struct sockaddr )))== -1) { //sizeof(struct sockaddr)
fprintf(stderr, "Binding Failure\n");
exit(1);
}
if ((listen(socket_fd, BACKLOG))== -1){
fprintf(stderr, "Listening Failure\n");
exit(1);
}
while(1) {
size = sizeof(struct sockaddr_in);
if ((client_fd = accept(socket_fd, (struct sockaddr *)&dest, &size)==-1)) {
//fprintf(stderr,"Accept Failure\n");
perror("accept");
exit(1);
}
printf("Server got connection from client %s\n", inet_ntoa(dest.sin_addr));
//buffer = "Hello World!! I am networking!!\n";
if ((num = recv(client_fd, buffer, 10239,0))== -1) {
//fprintf(stderr,"Error in receiving message!!\n");
perror("recv");
exit(1);
}
// num = recv(client_fd, buffer, sizeof(buffer),0);
buffer[num] = '\0';
printf("Message received: %s\n", buffer);
close(client_fd);
return 0;
//close(socket_fd);
}
}
Client:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#define PORT 3490
int main(int argc, char *argv[])
{
struct sockaddr_in server_info;
struct hostent *he;
int socket_fd,num;
char *buffer;
if (argc != 2) {
fprintf(stderr, "Usage: client hostname\n");
exit(1);
}
if ((he = gethostbyname(argv[1]))==NULL) {
fprintf(stderr, "Cannot get host name\n");
exit(1);
}
if ((socket_fd = socket(AF_INET, SOCK_STREAM, 0))== -1) {
fprintf(stderr, "Socket Failure!!\n");
exit(1);
}
memset(&server_info, 0, sizeof(server_info));
server_info.sin_family = AF_INET;
server_info.sin_port = htons(PORT);
server_info.sin_addr = *((struct in_addr *)he->h_addr);
if (connect(socket_fd, (struct sockaddr *)&server_info, sizeof(struct sockaddr))<0) {
//fprintf(stderr, "Connection Failure\n");
perror("connect");
exit(1);
}
buffer = "Hello World!! I am networking!!\n";
if ((send(socket_fd,buffer, sizeof(buffer),0))== -1) {
fprintf(stderr, "Failure Sending Message\n");
close(socket_fd);
exit(1);
}
else {
printf("Message being sent: %s\n",buffer);
}
close(socket_fd);
}
I ran the server under gdb, and discovered that client_fd is 0 after the call to accept(). This is an invalid socket fd, so I looked at that line of code and noticed that the closing parenthesis is wrong:
if ((client_fd = accept(socket_fd, (struct sockaddr *)&dest, &size)==-1)) {
should be:
if ((client_fd = accept(socket_fd, (struct sockaddr *)&dest, &size))==-1) {
Otherwise, it's doing the comparison first and then assigning the comparison to client_fd, whereas you want the assignment of the socket, followed by the comparison.
To avoid this exact kind of frustrating bug, it's generally considered best practice to not put assignments inside of 'if' statements. I would recommend instead:
client_fd = accept(...);
if (client_fd < 0) { ... }
Also, in the client, the call to send() uses "sizeof(buffer)". 'buffer' is a char*, and the sizeof a pointer is 4 (on a 32-bit system), so only 'Hell' will be sent. To send the full string, use "strlen(buffer)" instead for the amount to send.
Your first problem is misplaced parentheses.
if ((client_fd = accept(socket_fd, (struct sockaddr *)&dest, &size)==-1)) {
should actually be
if ((client_fd = accept(socket_fd, (struct sockaddr *)&dest, &size))==-1) {
As you currently have it, client_fd will be assigned to the result of the equality test between the return value of accept() and -1 and thus will always be zero in case of success.
This is one reason why many programmers avoid assignments in if statements. If written like this
client_fd = accept(socket_fd, (struct sockaddr *)&dest, &size);
if (client_fd == -1) {
then the error can't occur.