C socket : connect error - invalid argument - c

I made a simple Process-based parallel socket program.
My client code reaches the connect part and throws an Invalid argument error, and my server doesn't ouput anything. just cursor...
I split the terminal in two to run the code.
I run the code with:
gcc -o p-server p-server.c -Wall
./p-server
gcc -o p-client p-client.c -Wall
The output is
[C] Connecting...
[C] Can't connect to a Server: Invalid argument
p-server.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/types.h>
//#include <sys/wait.h>
#define BUFFSIZE 4096
#define SERVERPORT 7799
int main(void){
int i, j, s_sock, c_sock;
struct sockaddr_in server_addr, client_addr;
socklen_t c_addr_size;
char buf[BUFFSIZE] = {0};
char hello[] = "Hello~ I am Server!\n";
//int option = 1;
//setsockopt(s_sock, SOL_SOCKET, SO_REUSEADDR, &option, sizeof(option));
bzero(&server_addr, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(SERVERPORT);
server_addr.sin_addr.s_addr = inet_addr("10.0.0.131");
s_sock = socket(AF_INET, SOCK_STREAM, 0);
if (bind(s_sock, (struct sockaddr *) &server_addr, sizeof(server_addr)) == -1) {
perror("[S] Can't bind a socket");
exit(1);
}
if(listen(s_sock, 5)) {
perror("[S] Can't listen");
exit(1);
}
c_addr_size = sizeof(client_addr);
for ( i=0; i<3; i++) {
if ((c_sock = accept(s_sock, (struct sockaddr *) &client_addr, sizeof(client_addr))) == -1 ){
perror("[S] Can't accept a connection");
exit(1);
}
printf("[S] Connected: client IP addr=%s port=%d\n", inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port));
//fork
switch(fork()){
case 0:
close(s_sock);
//1. say hello to client
if(send(c_sock, hello, sizeof(hello)+1, 0) == -1) {
perror("[S] Can't send message");
exit(1);
}
printf("[S] I said Hello to Client!\n");
//2. recv msg from client
if(recv(c_sock, buf, BUFFSIZE, 0) == -1) {
perror("[S] Can't receive message");
exit(1);
}
printf("[S] Client says: %s\n", buf);
exit(0);
}
close(c_sock);
}
/*
for(j=0; j<3; j++){
wait(&status);
printf("Patren waits %d\n"), wstatus;
}*/
}
p-client.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#define BUFFSIZE 4096
#define SERVERPORT 7799
int main(void){
int c_sock;
struct sockaddr_in server_addr;
socklen_t c_addr_size;
char buf[BUFFSIZE] = {0};
char hello[] = "Hi~I am Client!\n";
if((c_sock = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
perror("socket");
exit(1);
}
bzero(&server_addr, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(SERVERPORT);
server_addr.sin_addr.s_addr = inet_addr("10.0.0.131");
printf("[C] Connecting...\n");
if (connect(c_sock, (struct sockaddr *) &server_addr, sizeof(server_addr) == -1)) {
perror("[C] Can't connect to a Server");
exit(1);
}
printf("[C] connected!\n");
//1. recv msg from server (maybe it's "hello")
if (recv(c_sock, buf, BUFFSIZE, 0) == -1) {
perror("[C] Can't receive message");
exit(1);
}
printf("[C] Server says: %s\n", buf);
//2. say hi to server
if(send(c_sock, hello, sizeof(hello)+1, 0) == -1) {
perror("[C] Can't send message");
exit(1);
}
printf("[C] I said Hi to Server!!\n");
printf("[C] I am going to sleep...\n");
sleep(10);
close(c_sock);
return 0;
}

Related

Problems sending messages to a server using TCP sockets

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)

How to write to the client twice?

I'm trying to send to the client the bits he has to read, then he has to read them. But for some reason he doesn't read the message, he only reads the bites,msgLength.I get the message form the server[server]The message was sent succefully.And the client is able to read only the msgLength, the msg is empty.
client:
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <errno.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <netdb.h>
#include <string.h>
#include <fcntl.h>
extern int errno;
int port;
int main(int argc, char *argv[])
{
int sd;
struct sockaddr_in server;
char msg[200];
int fd;
char msgLength[200];
if (argc != 3)
{
printf("Sintax: %s <adress_server> <port>\n", argv[0]);
return -1;
}
port = atoi(argv[2]);
if ((sd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
{
perror("Error on socket().\n");
return errno;
}
server.sin_family = AF_INET;
server.sin_addr.s_addr = inet_addr(argv[1]);
server.sin_port = htons(port);
if (connect(sd, (struct sockaddr *)&server, sizeof(struct sockaddr)) == -1)
{
perror("[client]Erorr on connect().\n");
return errno;
}
if (recv(sd, msgLength, 2,0) < 0)
{
perror("[client]Erorr on recv() from the server.\n");
return errno;
}
bzero(msg,100);
if (recv(sd, msg, 22,0)<0){
perror("[client]Erorr on the second recv() from the server.\n");
return errno;
}
printf("msgLength: %s\n",msgLength);
printf("[client]The message recived is: %s\n", msg);
close(sd);
}
server:
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <errno.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/wait.h>
#define PORT 2024
extern int errno;
int main()
{
struct sockaddr_in server; r
struct sockaddr_in from;
char msg[100];
char msgrasp[100] = " ";
int sd;
pid_t pid;
if ((sd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
{
perror("[server]Erorr on the socket().\n");
return errno;
}
bzero(&server, sizeof(server));
bzero(&from, sizeof(from));
server.sin_family = AF_INET;
server.sin_addr.s_addr = htonl(INADDR_ANY);
server.sin_port = htons(PORT);
int optval = 1;
setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval));
setsockopt(sd, SOL_SOCKET, SO_REUSEPORT, &optval, sizeof(optval));
*/
if (bind(sd, (struct sockaddr *)&server, sizeof(struct sockaddr)) == -1)
{
perror("[server]Erorr on the bind().\n");
return errno;
}
if (listen(sd, 5) == -1)
{
perror("[server]Erorr on listen().\n");
return errno;
}
while (1)
{
int client;
int length = sizeof(from);
printf("[server]We wait on the port %d...\n", PORT);
fflush(stdout);
client = accept(sd, (struct sockaddr *)&from, &length);
if (client < 0)
{
perror("[server]Erorr on accept().\n");
continue;
}
switch (pid = fork())
{
case -1:
perror("fork");
exit(1);
break;
case 0:
close(sd);
bzero(msg, 100);
printf("[server]Sending the text...\n");
fflush(stdout);
int fd1 = open("ToSend.txt", O_RDONLY);
char msgLength[100];
read(fd1, msgrasp, 100);
sprintf(msgLength,"%ld",strlen(msgrasp)+1);
printf("msgLength: %d\n",atoi(msgLength));
if ((send(client,msgLength,sizeof(msgLength),0) && send(client, msgrasp, atoi(msgLength),0)) <= 0)
{
perror("[server]Erorr on send() to the client.\n");
continue;
}
else
printf("[server]The message was sent succefully.\n");
exit(2);
default:
wait(NULL);
close(client);
break;
}
}
}
I solved it. The problem was that the server was sending sizeof(msgLength) witch is 100, and the client was reading just 2. If i replace sizeof(msgLength) with strlen(msgLength)+1 it works just fine. Thank you all for your time.

C Server - Print Received Massage?

I send this C Server a message w/ netcat.
echo <message> | nc <ip> <port>
it prints:
Client IP : <ip>
I want it to also print:
Client Message : <message>
C SERVER
#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 <arpa/inet.h>
#include <err.h>
char response[] = "hi";
int main()
{
int one = 1, client_fd;
struct sockaddr_in svr_addr, cli_addr;
socklen_t sin_len = sizeof(cli_addr);
int sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock < 0)
err(1, "can't open socket");
setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(int));
int port = 85;
svr_addr.sin_family = AF_INET;
svr_addr.sin_addr.s_addr = INADDR_ANY;
svr_addr.sin_port = htons(port);
if (bind(sock, (struct sockaddr *) &svr_addr, sizeof(svr_addr)) == -1) {
close(sock);
err(1, "Can't bind");
}
listen(sock, 5);
while (1) {
client_fd = accept(sock, (struct sockaddr *) &cli_addr, &sin_len);
printf("Client IP : [%s]\n", inet_ntoa(cli_addr.sin_addr));
if (client_fd == -1) {
perror("Can't accept");
continue;
}
write(client_fd, response, sizeof(response) - 1); /*-1:'\0'*/
close(client_fd);
}
}
You just have to read data from the socket (after the accept call, once you've checked that client_fd is usable):
if (client_fd == -1) {
perror("Can't accept");
continue;
}
printf("Client Message : <");
/* buffer to store result */
char buffer[64] = "";
/* while we can read from socket */
while (read(client_fd, buffer, sizeof buffer-1) > 0)
{
/* write what have been read */
printf("%s", buffer);
}
puts(">");
write(client_fd, response, sizeof(response) - 1); /*-1:'\0'*/
close(client_fd);
You could also use recv function.

Client can't receive messages from server?

I'm writing 2 small test programs in C (client/server) and I'm having trouble sending messages from the server to the client (but the other way around works just fine). The server says it sent 20 bytes, but on the client's end it says "failed to receive data". I would appreciate any help, thank you so much! My code is below:
Server:
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <string.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <netinet/in.h>
int main(int argc, char* argv[])
{
int sockfd, client_sockfd;
struct sockaddr_in server;
int reading, fileSize;
int i; //counter
int bytesSent;
char test[20] = "test message\n";
memset(&server, 0, sizeof(server));
server.sin_family = AF_INET;
server.sin_port = htons(atoi(argv[1])); //assign port to listen to
server.sin_addr.s_addr = INADDR_ANY; //IP address
if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) //create socket failed
{
perror("socket");
exit(1);
}
if(bind(sockfd, (struct sockaddr *) &server, sizeof(server)) == -1) //connect server socket to specified port
{
perror("bind call failed");
exit(1);
}
//printf("listening to port %d\n", server.sin_port);
if(listen(sockfd, 5) == -1) //queue size of 5
{
perror("listen call failed");
exit(1);
}
while(1) //infinite loop to process connections from clients
{
client_sockfd = accept(sockfd, NULL, NULL); //accept anything
if(client_sockfd == -1)
perror("accept call failed");
bytesSent = send(client_sockfd, test, 20, 0);
printf("bytes sent: %d\n", bytesSent);
}
close(client_sockfd);
close(sockfd);
return 0;
}
Client:
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <string.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <fcntl.h>
#include <errno.h>
int main(int argc, char* argv[])
{
int sockfd;
struct sockaddr_in server;
struct hostent *server_ip_address;
server_ip_address = gethostbyname("eos-class.engr.oregonstate.edu");
int sent; //number of bytes sent
int received; //number of bytes received
char passedMsg[20]; //holds received message
if(server_ip_address == NULL)
{
fprintf(stderr, "could not resolve server host name\n");
exit(1);
}
memset(&server, 0, sizeof(server));
server.sin_family = AF_INET;
server.sin_port = htons(atoi(argv[3])); //assign port to connect to
memcpy(&server.sin_addr, server_ip_address->h_addr, server_ip_address->h_length);
if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) //create socket failed
{
perror("socket");
exit(1);
}
if(connect(sockfd, (struct sockaddr *) &server, sizeof(server)) == -1) //connect socket to remote address failed
{
printf("tried to connect to port %d\n", server.sin_port);
perror("connect");
exit(1);
}
if((received = recv(sockfd, passedMsg, 20, 0)) < 0);
{
printf("Failed to receive data\n");
exit(1);
}
printf("Received message: %s\n", passedMsg);
close(sockfd);
return 0;
}
In your client code, in the error checking for recv, change printf to perror. If you do, the output will be:
Failed to receive data: Success
So the recv call was successful, but the error code ran anyway. Why? Let's take a closer look at that if statement:
// what's this? ----v
if((received = recv(sockfd, passedMsg, 20, 0)) < 0);
{
printf("Failed to receive data\n");
exit(1);
}
There's a stray ; after the condition in the if statement. This means that the if statement does nothing if the condition is true, and that the following block is not the body of the if but an independent block that always runs.
Get rid of the extra ; and you get the expected results.

C recv function behavior

This is my two pieces of code:
server.c
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/timeb.h>
#include <string.h>
#include <unistd.h>
#define BYTES_NR 64
#define MSG_NR 512
int main(int argc, char *argv[]) {
char buf[BYTES_NR];
int sock,length;
struct sockaddr_in server,client;
int rval,i;
if(argc !=2) {
fprintf(stderr,"Usage: %s port\n",argv[0]);
exit(-1);
}
sock = socket(AF_INET,SOCK_DGRAM,0);
if(sock<0) {
perror("opening stream socket");
exit(1);
}
server.sin_family = AF_INET;
server.sin_addr.s_addr= INADDR_ANY;
server.sin_port = htons(atoi(argv[1]));
if (bind(sock,(struct sockaddr *)&server,sizeof(server))<0) {
perror("binding stream socket");
exit(1);
}
length = sizeof(server);
if(getsockname(sock,(struct sockaddr *)&server, (socklen_t *)&length)<0){
perror("getting socket name");
exit(1);
}
printf("Socket port #%d\n",ntohs(server.sin_port));
printf("test");
while(1) {
do {
printf("test2");
bzero(buf,sizeof(buf));
rval = recvfrom(sock,buf,sizeof(buf), 0, (struct sockaddr *)&client, (socklen_t *)&length );
if(rval<0)
perror("reading stream message");
i=0;
if(rval==0)
printf("Ending connection\n");
else {
printf("Message received: sending back\n");
strcat(buf,"*");
if (sendto(sock,buf,sizeof(buf),0,(struct sockaddr *)&client,sizeof(client))<0)
perror("writing on stream socket");
}
} while(rval !=0);
}
return 0;
}
client.c
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/time.h>
#include <unistd.h>
#define BYTES_NR 64
#define MSG_NR 512
int main(int argc, char *argv[]) {
char buf[BYTES_NR];
char buf2[BYTES_NR];
char msg[MSG_NR][BYTES_NR];
char answ[MSG_NR][BYTES_NR];
struct timeval xstime[MSG_NR];
struct timeval xftime[MSG_NR];
int i,sock,rval,length;
unsigned long delay;
struct sockaddr_in server,client;
struct hostent *hp, *gethostbyname();
if(argc !=3) {
fprintf(stderr,"Usage: %s servername serverport\n",argv[0]);
exit(-1);
}
for(i=0;i<MSG_NR;i++) {
sprintf(&msg[i][0],"%d",i);
}
sock= socket(AF_INET,SOCK_DGRAM,0);
if(sock<0) {
perror("opening stream socket");
exit(1);
}
client.sin_family= AF_INET;
client.sin_addr.s_addr = INADDR_ANY;
client.sin_port = htons(0);
if (bind(sock,(struct sockaddr *)&client,sizeof(client)) <0) {
perror("sending datagram message");
exit(1);
}
length= sizeof(client);
if(getsockname(sock,(struct sockaddr *)&server,(socklen_t *)&length)<0) {
perror("getting socket name");
exit(1);
}
printf("Socket port #%d\n",ntohs(client.sin_port));
hp = gethostbyname(argv[1]);
if (hp == 0) {
fprintf(stderr,"%s :unknow host",argv[1]);
exit(2);
}
bcopy( (char *)hp ->h_addr, (char *)&server.sin_addr,hp ->h_length);
server.sin_family = AF_INET;
server.sin_port = htons(atoi(argv[2]));
for(i=0;i<MSG_NR;i++) {
printf("ciclo-");
strcpy(buf,msg[i]);
gettimeofday(&xstime[i],NULL);
if(sendto(sock, buf, sizeof(buf), 0, (struct sockaddr *)&server, sizeof(server)) < 0)
perror("sendto problem");
if((rval = read(sock,buf2,sizeof(buf2)))<0)
perror("reading stream message");
strcpy(answ[i],buf2);
gettimeofday(&xftime[i],NULL);
}
close(sock);
for (i=0; i<MSG_NR; i++) {
delay = (xftime[i].tv_sec-xstime[i].tv_sec)*1000000.+(xftime[i].tv_usec-xstime[i].tv_usec);
printf("msg %d [%s]: %0.3f ms\n",i,answ[i],delay/1000.);
}
return 0;
}
On the server side, why the printf that prints "test" does not operate before a client arrives with a request to send message? The same is true for the second printf that print "test2".
There's probably something conceptual that escapes me!
If i comment recv , the flow of execution returns normal.
This has nothing to do with recv. Change to:
printf("test\n");
By default, stdout is line-buffered, so you don't see anything until a newline is printed.
If you don't want to print a newline, you can use fflush(stdout); after each printf to print the current buffer. You can also use:
setvbuf(stdout, NULL, _IONBF, BUFSIZ);
to disable output buffering.

Resources