Use of connect after recvfrom with socket - c

Hi i want to wait the first message of a client as a server with a UDP Protocol so i send a message when I create the client socket and I use a recvfrom to get the message and the adress of the client.It works pretty good I can read the message in my buffer but after this operation I try to connect the server to the client address but this operation return a value of -1 for the connect process and I don't understand the reason.Here is my function wait for client the error is at the end when I try to connect to clientaddr.
int wait_for_client(int sfd){
struct sockaddr_in clientaddr;
int len;
char buf[32];
len = sizeof(clientaddr);
int rec_stat = recvfrom(sfd, buf, 32, 0, (struct sockaddr*)&clientaddr, (socklen_t *)&len);
if(rec_stat<0){
printf("echec de receive");
fflush(stdout);
return -1;
}
printf("%s\n",buf);
fflush(stdout);
int connect_status = connect(sfd,(struct sockaddr *)&clientaddr,sizeof(clientaddr));
if(connect_status == -1){
printf("failed to connect to client\n");
fflush(stdout);
return -1;
}
printf("%s\n",buf);
return sfd;
}

The problem was because my clientaddr is declared as sockaddr_in but my client was created as sockaddr_in6. So the mistake was the struct of my clientaddr

Related

Can I have more than one socket file descriptor per client?

I'm coding a server program and a client program. As the client process can be infinite (it only ends after an interruption), I thought I could create a thread in the client process to disconnect itself when the server process disconnects, so the server could send a message to the client in order to disconnect the client too.
The issue here is that connecting the client to the server only returns one socket file descriptor which can be in use at the time when the server disconnects and use some data in the socket buffer so it would affect negatively to the main purpose of the program so I'd like to use another socket file descriptor to the server for the disconnection thread.
How can I do this?
This are the functions I use to connect both processes:
SERVER:
int socketConfig (connection_info cinfo) {
int socketfd = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (socketfd < 0) {
write(1, "Socket error\n", strlen("Socket error\n"));
return -1;
}
struct sockaddr_in s_addr;
memset (&s_addr, 0, sizeof (s_addr));
s_addr.sin_family = AF_INET;
s_addr.sin_port = htons(cinfo.port);
s_addr.sin_addr.s_addr = INADDR_ANY;
if (bind (socketfd, (void *) &s_addr, sizeof (s_addr)) < 0) {
write(1, "Bind error\n", strlen("Bind error\n"));
return -1;
}
listen(socketfd, 3);
return socketfd;
}
int receiveClient(int serverfd) {
struct sockaddr_in client;
socklen_t len = sizeof(client);
return accept(serverfd, (void *) &client, &len);
}
CLIENT:
int connect_to_server(Config config) {
struct sockaddr_in client;
int sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
write(1, "Connecting Jack...\n", strlen("Connecting Jack...\n"));
if (sockfd < 0) {
write(1, "Error creating the socket\n", strlen("Error creating the socket\n"));
return -1;
}
memset(&client, 0, sizeof(client));
client.sin_family = AF_INET;
client.sin_port = htons(config.port_jack);
if (inet_aton(config.ip_jack, &client.sin_addr) == 0) {
write(1, "Invalid IP address\n", strlen("Invalid IP address\n"));
return -1;
}
if (connect(sockfd, (void *) &client, sizeof(client)) < 0) {
write(1, "Error connecting to Jack\n", strlen("Error connecting to Jack\n"));
return -1;
}
return sockfd;
}
The server does not need to "send a message" when it closes the connection, the TCP/IP stack will do that for you.
Then the client when doing a read will receive 0 bytes to indicate the other side closed the connection. There is no need for a separate socket.
Another way to do, is to use the signal.h library : the client process will interrupt itself and call a function you specified when it will receive a signal sent by the server process

Why is Connect() returning a negative value?

#include<io.h>
#include<stdio.h>
#include<winsock2.h>
#include <ctype.h>
#include<string.h>
#include<strings.h>
#define MY_PORT 8989 //defining the port for the socket
#define MAXBUF 256
int main(int argc , char *argv[])
{
//char str[MAXBUF];
int a;
WSADATA wsa;
SOCKET sockfd , clientfd; //SOCKET is a data type. We initialize two variables of the data type Socket here
struct sockaddr_in self; //structure for the family,port and IP address of the socket (Socket descriptors)
char buffer[MAXBUF]; // this is a character array that will receive the message from the client and we will use this to manipulate
//char message[MAXBUF];
printf("\nInitialising Winsock...");
if (WSAStartup(MAKEWORD(2,2),&wsa) != 0) //WSASTARUP is used to tell windows to get ready for a connection and if it returns a value 0, windows is ready
{
printf("Failed. Error Code : %d",WSAGetLastError());
return 1;
}
printf("Initialised.\n");
/*---create streaming socket---*/
if ( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0 ) //socket is created using a function called socket
//using AF_INET means that we are using TCP/IP family
//the if statement here checks whether or not the value returned by the socket is negative or not. If it is negative that means there is some sort of an error
{
perror("Socket");
exit(errno);
}
printf("Socket created.\n");
self.sin_family = AF_INET;
self.sin_port = htons(MY_PORT);
self.sin_addr.s_addr = htonl(INADDR_ANY);
memset(&self,'\0', sizeof(self));
/*The connect function below is used to establish a connection between the client and the server*/
if (connect(sockfd, (struct sockaddr*)&self, sizeof(self)) <0)
{
printf("connection with the server failed...\n");
exit(0);
}
else
printf("connected to the server..\n");
printf("Please enter message: ");
memset(buffer, 0, sizeof (buffer));
fgets(buffer, MAXBUF, stdin); //fgets is used here to get whatever is inside the buffer
while (1)
{
/*struct sockaddr_in client_addr;
int addrlen=sizeof(client_addr);*/
/*---accept a connection (creating a data pipe)---*/
a= write(sockfd, buffer, sizeof(buffer));
if(a<0){
printf("Error");
}
// a= recv(clientfd, buffer, MAXBUF, 0);
//accept(clientfd, (struct sockaddr*)&client_addr, &addrlen);
a= read(sockfd, buffer, sizeof(buffer));
if(a<0){
printf("Error");
}
if (strncmp("QUIT", buffer, 4) == 0) {
printf("Server Exit...\n");
break;
}
}
close(sockfd); //close the sockfd
WSACleanup(); // windows socket is cleaned up
return 0;
}
The code works completely fine but for some reason, which I can't wrap my head around the connect function keeps on returning a negative value, or at least a value that is not zero. The server I am using with this client works for other clients, so I know for a fact that there is nothing wrong with it.
Your help will be much appreciated.
self.sin_family = AF_INET;
self.sin_port = htons(MY_PORT);
self.sin_addr.s_addr = htonl(INADDR_ANY);
memset(&self,'\0', sizeof(self));
In this code you set all the values of self and then you just clear self with memset. I'm pretty sure that this makes no sense and likely is the cause of the error you see, i.e. no useful parameters given for connect.
Even without this erroneous memset the code does not make much sense: you are trying to connect to INADDR_ANY but there is no such IP address to connect to. INADDR_ANY means on the server side to listen on every address of the machine - on the client side it cannot be used but instead the real IP address have to be used, like 127.0.0.1 for localhost.

Socket Programming: Client printing garbage string

I am new to Network Programming and the first program we were supposed to do in our lab was a program where two systems, client and the server send messages to each other. My program has no compiler errors, but whenever a message is sent over the network, it is not being displayed properly on the other end. Instead an unreadable box is being displayed (I think a garbage string is being printed but don't know why).
View the screenshot here
The codes:
client.c
int main()
{
char server_message[256]="You have reached the server!!\n";
//create a socket
int nw_socket;
nw_socket=socket(AF_INET,SOCK_STREAM,0);
//specify address for socket
struct sockaddr_in server_address;
server_address.sin_family = AF_INET;
server_address.sin_port = htons(9999);
server_address.sin_addr.s_addr = INADDR_ANY;
//establish a connection
int connection_status = connect(nw_socket, (struct sockaddr *) & server_address, sizeof(server_address));
//check for errors
if(connection_status==-1)
{
perror("There was a problem initiating the connection.\n");
}
else
{
printf("The connection was successful.\n");
}
int send_val = send(nw_socket,server_message,sizeof(server_message),0);
if(send_val==-1)
perror("\nError while sending: ");
//receive data
char data[256];
int recv_val=recv(nw_socket,data,sizeof(data),0);
if(recv_val==-1)
perror("\nError while receiving: ");
printf("The server's response was: %s\n",data );
//close the socket
close(nw_socket);
return 0;
}
server.c
int main()
{
char server_message[256]="You have reached the server!!\n";
//create a new socket
int server_socket=socket(AF_INET,SOCK_STREAM,0);
struct sockaddr_in server_connection;
server_connection.sin_family=AF_INET;
server_connection.sin_port=htons(9999);
server_connection.sin_addr.s_addr=INADDR_ANY;
int bind_val=bind(server_socket, (struct sockaddr *) & server_connection, sizeof(server_connection));
if(bind_val==-1)
perror("\nError while binding: ");
listen(server_socket,6);
int client_socket=accept(server_socket, NULL, NULL);
if(client_socket==-1)
perror("\nError while accepting: ");
int send_val= send(server_socket,server_message,sizeof(server_message),0);
if(send_val==-1)
perror("\nError while sending: ");
char data[256];
recv(server_socket,data,sizeof(data),0);
close(server_socket);
return 0;
}
How do I fix this? Thanks in advance.
You are using the listening socket when sending a message in the server:
int send_val= send(server_socket,server_message,sizeof(server_message),0);
You should be using the socket connected to the client:
int send_val = send(client_socket,server_message,sizeof(server_message),0);

How to send message to a server through socket in 'C' when server is started after the client?

I have made a client (in C) which is trying to connect to a server (in VB 6.0) till the connection is established. If the server is ready t listen and then we run the client program trying to connect and send a message, it works fine and also the response is received on the client side.
But when we start the client program before server, it tries to connect after a short interval to the server until it gets connected (in an infinite loop). When we switch on the server, the client connects successfully to the server but doesn't send the message. I am not able to find the problem in this case.
I have checked in the 'wireshark' that client doesn't send any message.
How come the program works fine when the server is running before the client and not in the other case?
Please suggest how to find the problem.
Here is the code for the client program:
int
tcp_send()
{
int sd, newSd, rc, i, cliSd, servLen, num, k, p;
struct sockaddr_in servAddr;
struct hostent *h;
char si[4];
char line[MAX_MSG];
char message[MAX_MSG];
struct timeval tp;
time_t now;
char msg[MAX_MSG];
char str[MAX_MSG];
strcpy(msg, "Hello World");
servAddr.sin_family = AF_INET;
servAddr.sin_addr.s_addr = inet_addr("111.1.1.11");
servAddr.sin_port = htons(SERVER_PORT);
/* create socket */
sd = socket(AF_INET, SOCK_STREAM, 0);
if(sd<0)
{
exit(1);
}
rc = -1;
for (;rc!=0;)
{
/* connect to server */
rc = connect(sd, (struct sockaddr *) &servAddr, sizeof(servAddr));
if(rc<0)
{
sleep(2);
}
}
memset(message, 0, sizeof(message));
memset(si, 0, sizeof(si));
num = strlen(msg);
integertostring(si, num, 4);
memcpy(message, si, 4);
memcpy(message + strlen(message), msg, strlen(msg));
rc = send(sd, message, strlen(message), 0);
if(rc<0)
{
close(sd);
exit(1);
}
sleep(1);
read_line(sd,line);
memset(line,0x0,MAX_MSG);
return SUCCESS;
}
Try to close the socket after connect has failed and recreate it again.

Socket programming: recv/read issue

EDIT: the code below has been fixed to receive and send properly AND to account for the actual bytes of messages sent annd recieved (latter thanks to EJP)
I'm programming with C in Unix.
I have server and client that are supposed to exchange msgs. While client seems to send messages fine, server doesn't receive the messages the client is sending. I've tried using recv() and read() (i know they are practically the same thing but with extra flags on recv()) but I have no luck and I'm not really sure what the problem really is.
I put sleep(3) in the client code after every time it sends a message but i see that once client and server are connected, server immediately closes without waiting for the incoming messages. What am i doing wrong?
This is the client-side code:
#define SERVER_TCP_PORT 11112
#define MAX_DATA_SIZE 500
int main(int argc, char * argv[])
{
int sockfd;
char * host;
char msg[MAX_DATA_SIZE];/* = "get my msg!\n";*/
int msg_len;
struct hostent * hp;
struct sockaddr_in client_address, server_address;
printf("y halo thar\n");
// looking up from the host database
if (argc == 2)
host = argv[1];
else
exit(1);
printf("sdf\n");
hp = gethostbyname(host);
if (!hp)
exit(1);
printf("host found\n");
// setting up address and port structure information
bzero((char * ) &server_address, sizeof(server_address)); // copy zeroes into string
server_address.sin_family = AF_INET;
bcopy(hp->h_addr, (char *) &server_address.sin_addr, hp->h_length);
server_address.sin_port = htons(SERVER_TCP_PORT);
printf("set\n");
// opening up socket
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0 )
exit(1);
printf("opened\n");
// connecting
if (connect(sockfd, (struct sockaddr *) &server_address, sizeof(server_address)) < 0)
exit(1);
printf("connected\n");
int i;
for (i = 0; i < MAX_DATA_SIZE; ++i)
{
msg[i] = '.';
}
msg[MAX_DATA_SIZE-1] = '\0';
for(i = 0; i < 11; i++)
{
// send message to connected socket
msg_len = write(sockfd, msg, MAX_DATA_SIZE);
if(msg_len < 1)
printf("notsent\n");
else
printf("%i bytes sent\n", msg_len);
// recieve messages from connected socket
msg_len = read(sockfd, msg, MAX_DATA_SIZE);
if (msg_len < 1)
printf("not recieved\n");
else
{
printf("%i bytes received\n", msg_len);
printf(msg);
printf("\n");
}
}
// close connection
close(sockfd);
printf("closed\n");
}
and this is the server side
#define SERVER_TCP_PORT 11112
#define MAX_DATA_SIZE 500
int main()
{
printf("o halo thar\n");
int sockfd, new_sockfd;
int client_addr_len;
char msg [MAX_DATA_SIZE];
int msg_len;
char got_msg [11] = "got ur msg\0";
struct sockaddr_in server_address, client_address;
// setting up address and port structure information
bzero((char * ) &server_address, sizeof(server_address)); // copy zeroes into string
server_address.sin_family = AF_INET;
server_address.sin_addr.s_addr = htonl(INADDR_ANY);
server_address.sin_port = htons(SERVER_TCP_PORT);
// opening up socket
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0 )
exit(1);
printf("socket is opened\n");
// binding
if (bind(sockfd, (struct sockaddr *) &server_address, sizeof(server_address)) < 0)
exit(1);
printf("socket is bound\n");
// listening
listen(sockfd,5);
printf("listening\n");
// block and wait for an incoming connection
client_addr_len = sizeof(client_address);
new_sockfd = accept(sockfd, (struct sockaddr *) &client_address, &client_addr_len);
if (new_sockfd < 0)
exit(1);
printf("accepted\n");
int i;
for( i = 0; i < 11; i++)
{
// recieve messages from connected socket
printf("waiting\n");
msg_len = read(new_sockfd, msg, MAX_DATA_SIZE);
if (msg_len < 1)
{
printf("no msg recieved\n");
}
else
{
printf("bytes recieved: %i\n", msg_len);
}
// send message to connected socket
msg_len = write(new_sockfd, got_msg, sizeof(got_msg));
if (msg_len < 1)
printf("not sent\n");
else
printf("%i bytes sent\n", msg_len);
}
// close connection
close(sockfd);
printf("socket closed. BYE! \n");
}
In the server code, the problem is on this line:
msg_len = read(sockfd, msg, MAX_DATA_SIZE);
You are calling read on sockfd, but you need to call read or recv on new_sockfd (the socket returned by accept()). new_sockfd is the one that's connected to the client (sockfd is used to accept further connections - eg if another client connects).
You should read from the socket returned by accept.
Try to call read on the socket returned from accept.
Receiver Side:
while(1)
{
len=read(sd,buff,sizeof(buff));
if(len==0)
{
//End of File receving.
break;
}
else
{
st=fwrite(buff,sizeof(char),len,fp);
}
}
Send Side:
while(!feof(fp))
{
len=fread(buff,sizeof(char),MW,fp);
if(len==0)
{
//EOF
st=write(cd,&d,sizeof(int));
break;
}
else
{
st=write(cd,buff,len);
}
}
is the implementation based on stream or datagram?
there are some problem with your operation flow. the server might start to read before client send anything.
since client and server are separated, you can imagine them running concurrently.
right after your server side "accept" connection request, there might be possibly some handshake overhead occurs or network delays causing server app to execute ahead in time, attempt to extract data but meet with errors (no data received yet).
you can try this out by adding sleep in server code after accept connection, where client should have enough time to send the data.
another better solution is to make data retrieval cope with empty buffer or asynchronous read.

Resources