C++ socket keeps receiving the same data - c++

I am using this code to receive data from a sensor through sockets. The problem is that I keep receiving the same output for every iteration of the for loop. However I receive a different number for every time I run the code but again, the same number keeps repeating. The sensor should send different every time data but thats not the case here.
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <netdb.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include "port.h"
#define BUFSIZE 2048
int
main(int argc, char **argv)
{
struct sockaddr_in myaddr; /* our address */
struct sockaddr_in remaddr; /* remote address */
socklen_t addrlen = sizeof(remaddr); /* length of addresses */
int recvlen; /* # bytes received */
int fd; /* our socket */
int msgcnt = 0; /* count # of messages we received */
unsigned char buf[BUFSIZE]; /* receive buffer */
/* create a UDP socket */
if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
perror("cannot create socket\n");
return 0;
}
/* bind the socket to any valid IP address and a specific port */
memset((char *)&myaddr, 0, sizeof(myaddr));
myaddr.sin_family = AF_INET;
myaddr.sin_addr.s_addr = htonl(INADDR_ANY);
myaddr.sin_port = htons(SERVICE_PORT);
if (bind(fd, (struct sockaddr *)&myaddr, sizeof(myaddr)) < 0) {
perror("bind failed");
return 0;
}
/* now loop, receiving data and printing what we received */
printf("waiting on port %d\n", SERVICE_PORT);
printf("%s \n \n", "We recieve 10 packets just to confirm the communication");
recvlen = recvfrom(fd, buf, BUFSIZE, 0, (struct sockaddr *)&remaddr, &addrlen);
if (recvlen > 0) {
buf[recvlen] = 0;
printf("received message: \"%u\" (%d bytes)\n", buf, recvlen);
}
else
printf("uh oh - something went wrong!\n");
sprintf(buf, "ack %d", msgcnt++);
printf("sending response \"%u\"\n", buf);
if (sendto(fd, buf, strlen(buf), 0, (struct sockaddr *)&remaddr, addrlen) < 0)
perror("sendto");
int temp = recvlen;
for (;;) {
recvlen = recvfrom(fd, buf, BUFSIZE, 0, (struct sockaddr *)&remaddr, &addrlen);
if (recvlen > 0) {
buf[recvlen] = 0;
printf("received message: \"%u\" (%d bytes)\n", buf, recvlen);
}
}
}
Edit:
Here is the output when i ran the code two seperate times:
trial run and
trial run 2

I believe the problem isn't with your networking code but rather with your printf() calls:
printf("received message: \"%u\" (%d bytes)\n", buf, recvlen);
You are specifying %u to print out the contents of buf, but buf is a char array (not an unsigned integer), so you probably want to be using %s instead.

Related

linux socket lose data when a delay is added before read

I am learning linux socket programming, I expect that server can read data, even I add a delay but it just drops the buffer data, and receive the recent data, that is why, Thanks. The code has been presented.
By the way, Could you show a common practice to deal with this kind of situation?
Server side C/C++ program to demonstrate Socket programming
#include <unistd.h>
#include <stdio.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <string.h>
#define PORT 8080
int main(int argc, char const *argv[])
{
int server_fd, new_socket, valread;
struct sockaddr_in address;
int opt = 1;
int addrlen = sizeof(address);
char buffer[1024] = {0};
const char hello[] = "Hello from server";
// Creating socket file descriptor
if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0)
{
perror("socket failed");
exit(EXIT_FAILURE);
}
// Forcefully attaching socket to the port 8080
if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT,
&opt, sizeof(opt)))
{
perror("setsockopt");
exit(EXIT_FAILURE);
}
address.sin_family = AF_INET;
address.sin_addr.s_addr = INADDR_ANY;
address.sin_port = htons(PORT);
// Forcefully attaching socket to the port 8080
if (bind(server_fd, (struct sockaddr *)&address,
sizeof(address)) < 0)
{
perror("bind failed");
exit(EXIT_FAILURE);
}
if (listen(server_fd, 3) < 0)
{
perror("listen");
exit(EXIT_FAILURE);
}
if ((new_socket = accept(server_fd, (struct sockaddr *)&address,
(socklen_t *)&addrlen)) < 0)
{
perror("accept");
exit(EXIT_FAILURE);
}
for (int i = 0;; i++)
{
sleep(5);
valread = read(new_socket, buffer, 1024);
printf("%s\n", buffer);
}
send(new_socket, hello, strlen(hello), 0);
printf("Hello message sent\n");
return 0;
}
Client side C/C++ program to demonstrate Socket programming
#include <stdio.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string>
#include <string.h>
#define PORT 8080
int main(int argc, char const *argv[])
{
int sock = 0, valread;
struct sockaddr_in serv_addr;
const char data[] = "Hello from client";
char buffer[1024] = {0};
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
printf("\n Socket creation error \n");
return -1;
}
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(PORT);
// Convert IPv4 and IPv6 addresses from text to binary form
if (inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr) <= 0)
{
printf("\nInvalid address/ Address not supported \n");
return -1;
}
if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0)
{
printf("\nConnection Failed \n");
return -1;
}
for (int i = 0;; i++)
{
sleep(1);
std::string hello = std::string(data) + std::to_string(i);
if (send(sock, hello.c_str(), hello.length() + 1, 0) != hello.length() + 1)
{
printf("error send %d \n", i);
}
printf("Hello message sent %d\n", i);
}
valread = read(sock, buffer, 1024);
printf("%s\n", buffer);
return 0;
}
The problem is, that the messages get concatenated in the socket. The socket represents a byte stream. Your sender puts bytes into the stream every second. On the first iteration, it writes "Hello from client0\0" (19 bytes) to the stream.
After one second, it writes "Hello from client1\0", and then "Hello from client2\0", "Hello from client3\0" and "Hello from client4\0", Now, after 5 Seconds, 5*19 = 95 bytes are written to the byte stream.
Now, the receiver calls valread = read(new_socket, buffer, 1024);. Guess what, it reads all 95 bytes (because you specified 1024 as buffer size) and sets valread to 95.
Then you call printf("%s\n", buffer);, which only prints the first 18 bytes of buffer, because there is a '\0' as 19th byte, which terminates '%s' format. Allthough 95 bytes are received, 76 bytes are missing in the output of your program.
If you use '\n' instead of '\0' as message separator and use write(1, buffer, valread) instead of printf("%s\n") on the receiving side, you will see all your data.
std::string hello = std::string(data) + std::to_string(i) + "\n";
if (send(sock, hello.c_str(), hello.length(), 0) != hello.length()) ...
Conclusion:
Stream sockets realize byte sreams, the do not preserve message boundaries.
If message bounaries must be preserved, you need to use a protocol on top of the stream to mark your message boundaries. The proptocol could be as simple as using '\n' as a message seaparator, as long as '\n' is not part of your message payload (e.g. when unsign a simple text protocol).
You block the server for 5 seconds and it cannot receive some messages from the client.
for (int i = 0;; i++)
{
sleep(5);
valread = read(new_socket, buffer, 1024);
printf("%s\n", buffer);
}
How can a client check if the server is receiving a message? I think this was discussed in Linux socket: How to make send() wait for recv()
P.S. It looks like there is a synchronizing piece of code, but you pulled it out of the loop.
Server:
}
send(new_socket, hello, strlen(hello), 0);
Client:
}
valread = read(sock, buffer, 1024);

UDP client stucks in recvfrom only in specific situation

I'm writing a C++ code that implements an UDP server and client.
The code works fine when I write two codes, one for the server and another for the client, as in this example : https://www.geeksforgeeks.org/udp-server-client-implementation-c/ .
What I'm trying to do is to write a client function and a server function in the same code. The ideia is that I select how the program is going to work with the command lines argument.
The problem is that, implementing this way and testing in two terminals running the same code, with different command line arguments, one for server and another for client, the client stucks in the recvfrom, when receiving the server response.
#include <unistd.h>
#include <stdio.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <string.h>
#include <arpa/inet.h>
#include <unistd.h>
#define MAXLINE 1024
#define PORT 32000
int send(){
int sockfd;
char buffer[MAXLINE];
char *hello = "Hello from server";
struct sockaddr_in servaddr, cliaddr;
// Creating socket file descriptor
if ( (sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0 ) {
perror("socket creation failed");
exit(EXIT_FAILURE);
}
memset(&servaddr, 0, sizeof(servaddr));
memset(&cliaddr, 0, sizeof(cliaddr));
// Filling server information
servaddr.sin_family = AF_INET; // IPv4
servaddr.sin_addr.s_addr = inet_addr("127.0.0.1");
servaddr.sin_port = htons(PORT);
// Bind the socket with the server address
if ( bind(sockfd, (const struct sockaddr *)&servaddr,
sizeof(servaddr)) < 0 )
{
perror("bind failed");
exit(EXIT_FAILURE);
}
socklen_t len;
int n;
n = recvfrom(sockfd, (char *)buffer, MAXLINE,
MSG_WAITALL, ( struct sockaddr *) &cliaddr,
&len);
buffer[n] = '\0';
printf("Client : %s\n", buffer);
sendto(sockfd, (const char *)hello, strlen(hello),
MSG_CONFIRM, (const struct sockaddr *) &cliaddr,
len);
printf("Hello message sent.\n");
return 0;
}
int receive(){
int sockfd;
char buffer[MAXLINE];
char *hello = "Hello from client";
struct sockaddr_in servaddr;
// Creating socket file descriptor
if ( (sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0 ) {
perror("socket creation failed");
exit(EXIT_FAILURE);
}
memset(&servaddr, 0, sizeof(servaddr));
// Filling server information
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(PORT);
servaddr.sin_addr.s_addr = inet_addr("127.0.0.1");
int n;
socklen_t len;
sendto(sockfd, (const char *)hello, strlen(hello),
MSG_CONFIRM, (const struct sockaddr *) &servaddr,
sizeof(servaddr));
printf("Hello message sent.\n");
n = recvfrom(sockfd, (char *)buffer, MAXLINE,
MSG_WAITALL, (struct sockaddr *) &servaddr,
&len);
buffer[n] = '\0';
printf("Server : %s\n", buffer);
return 0;
}
int main(int argc, char const *argv[]) {
int command = atoi(argv[1]);
if(command == 0){
send();
}
if(command == 1){
receive();
}
return 0;
}
The expected results is something like this, that i get when running the client and the server on separated codes:
Server side:
Hello from client
Hello message sent
Client side:
Hello message sent
Hello from server
But what I get when running the code above is
Server side:
Hello from client
Hello message sent
Client side:
Hello message sent
---gets stucked here---
What am i doing wrong?
In your send() function, you are not initializing len to the length of the buffer where recvfrom can store the client address.
According to the man page for recvfrom:
ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,
struct sockaddr *src_addr, socklen_t *addrlen);
If src_addr is not NULL, and the underlying protocol provides the
source address of the message, that source address is placed in the
buffer pointed to by src_addr. In this case, addrlen is a value-result
argument. Before the call, it should be initialized to the size of the
buffer associated with src_addr. Upon return, addrlen is updated to
contain the actual size of the source address.
It's not working because the client address isn't being properly received so the response message is being sent to the wrong address. To resolve your problem, you just need to initialize len before the call to recvfrom:
socklen_t len = sizeof(cliaddr); // The size of the buffer you're passing to store the client address

Multipath udp connections

I programmed client and server codes. Both client and server have two interfaces and two separate IP addresses. To check the result, i made two tap loopbacks.
And then, i check the server and client. It seems that client is sending packets over both sockets but server only receives packets from one socket.
Could you please guide me what is the problem with my code or maybe the loopbaks?
client
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <string.h>
#include <iostream>
#include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <netinet/in.h>
#include <netdb.h>
#include <sys/socket.h>
#define BUFLEN 2048
#define MSGS 5 /* number of messages to send */
int main(void)
{
struct sockaddr_in myaddr, remaddr;
int fd, i, slen=sizeof(remaddr);
char buf[BUFLEN]; /* message buffer */
int recvlen; /* # bytes in acknowledgement message */
char *server = "192.168.10.10"; /* change this to use a different server */
//////////////////////////////////
struct sockaddr_in myaddr2, remaddr2;
int fd2, slen2=sizeof(remaddr2);
char buf2[BUFLEN]; /* message buffer */
int recvlen2; /* # bytes in acknowledgement message */
char *server2 = "192.168.11.11"; /* change this to use a different server */
//////////////////////////////
/* create a socket */
if ((fd=socket(AF_INET, SOCK_DGRAM, 0))==-1)
printf("socket created\n");
/////////////////////////////
if ((fd2=socket(AF_INET, SOCK_DGRAM, 0))==-1)
printf("socket2 created\n");
/////////////////////////////
/* bind fd and fd2 */
memset((char *)&myaddr, 0, sizeof(myaddr));
myaddr.sin_family = AF_INET;
//myaddr.sin_addr.s_addr = htonl(INADDR_ANY);
inet_pton(AF_INET, "192.168.10.10", &myaddr.sin_addr.s_addr);
myaddr.sin_port = htons(2000);
/////////////////////////////
memset((char *)&myaddr2, 0, sizeof(myaddr2));
myaddr2.sin_family = AF_INET;
//myaddr.sin_addr.s_addr = htonl(INADDR_ANY);
inet_pton(AF_INET, "192.168.11.11", &myaddr2.sin_addr.s_addr);
myaddr2.sin_port = htons(2001);
/////////////////////////////
if (bind(fd, (struct sockaddr *)&myaddr, sizeof(myaddr)) < 0) {
perror("bind failed");
return 0;
}
/////////////////////////////
if (bind(fd2, (struct sockaddr *)&myaddr2, sizeof(myaddr2)) < 0) {
perror("bind2 failed");
return 0;
}
/////////////////////////////
// printf("binding ip %s to port %d\n", myaddr.sin_addr.s_addr, myaddr.sin_port);
/* now define remaddr, the address to whom we want to send messages */
/* For convenience, the host address is expressed as a numeric IP address */
/* that we will convert to a binary format via inet_aton */
memset((char *) &remaddr, 0, sizeof(remaddr));
remaddr.sin_family = AF_INET;
remaddr.sin_port = htons(3000);
if (inet_aton(server, &remaddr.sin_addr)==0) {
fprintf(stderr, "inet_aton() failed\n");
exit(1);
}
/////////////////////////////
memset((char *) &remaddr2, 0, sizeof(remaddr2));
remaddr2.sin_family = AF_INET;
remaddr2.sin_port = htons(4000);
if (inet_aton(server2, &remaddr2.sin_addr)==0) {
fprintf(stderr, "inet_aton2() failed\n");
exit(1);
}
/////////////////////////////
/* now let's send the messages */
for (i=0; i < MSGS; i++) {
printf("Sending packet %d to %s port %d\n", i, server, remaddr.sin_port);
sprintf(buf, "This is packet %d", i);
if (sendto(fd, buf, strlen(buf), 0, (struct sockaddr *)&remaddr, slen)==-1) {
perror("sendto");
exit(1);
}
printf("socket %i SENT A PACKET \n", fd);
printf("Sending packet %d to %s port %d\n", i, server2, remaddr2.sin_port);
sprintf(buf2, "This is packet %d", i);
if (sendto(fd2, buf2, strlen(buf2), 0, (struct sockaddr *)&remaddr2, slen2)==-1) {
perror("sendto2");
exit(1);
}
printf("socket %i SENT A PACKET \n", fd2);
}
close(fd);
close(fd2);
return 0;
}
server
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <string.h>
#include <errno.h>
#include <iostream>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/select.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <netdb.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#define BUFSIZE 2048
int
main(int argc, char **argv)
{
int n;
fd_set readfds;
struct timeval tv;
struct sockaddr_in myaddr; /* our address */
struct sockaddr_in remaddr; /* remote address */
socklen_t addrlen = sizeof(remaddr); /* length of addresses */
int recvlen; /* # bytes received */
int fd; /* our socket */
unsigned char buf[BUFSIZE]; /* receive buffer */
/////////////////////
struct sockaddr_in myaddr2; /* our address */
struct sockaddr_in remaddr2; /* remote address */
socklen_t addrlen2 = sizeof(remaddr2); /* length of addresses */
int recvlen2; /* # bytes received */
int fd2; /* our socket */
unsigned char buf2[BUFSIZE]; /* receive buffer */
/////////////////////
/* create a UDP socket */
if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
perror("cannot create socket\n");
return 0;
}
printf("socket %i is open \n", fd);
///////////////////////////////
if ((fd2 = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
perror("cannot create socket2\n");
return 0;
}
printf("socket %i is open \n", fd2);
///////////////////////////////
// clear the set ahead of time
FD_ZERO(&readfds);
// add our descriptors to the set
FD_SET(fd, &readfds);
FD_SET(fd2, &readfds);
// since we got s2 second, it's the "greater", so we use that for
// the n param in select()
n = fd2 + 1;
/* bind the socket to any valid IP address and a specific port */
memset((char *)&myaddr, 0, sizeof(myaddr));
myaddr.sin_family = AF_INET;
//myaddr.sin_addr.s_addr = htonl(INADDR_ANY);
inet_pton(AF_INET, "192.168.10.10", &myaddr.sin_addr.s_addr);
myaddr.sin_port = htons(3000);
if (bind(fd, (struct sockaddr *)&myaddr, sizeof(myaddr)) < 0) {
perror("bind failed");
return 0;
}
///////////////////////////
memset((char *)&myaddr2, 0, sizeof(myaddr2));
myaddr2.sin_family = AF_INET;
//myaddr2.sin_addr.s_addr = htonl(INADDR_ANY);
inet_pton(AF_INET, "192.168.11.11", &myaddr2.sin_addr.s_addr);
myaddr2.sin_port = htons(4000);
if (bind(fd2, (struct sockaddr *)&myaddr2, sizeof(myaddr2)) < 0) {
perror("bind2 failed");
return 0;
}
// wait until either socket has data ready to be recv()d (timeout 10.5 secs)
tv.tv_sec = 50;
tv.tv_usec = 500000;
for (;;) {
int rv = select(n, &readfds, NULL, NULL, &tv);
if (rv == -1) {
perror("select"); // error occurred in select()
} else if (rv == 0) {
printf("Timeout occurred! No data after 10.5 seconds.\n");
} else {
// one or both of the descriptors have data
if (FD_ISSET(fd, &readfds)) {
printf("socket %i RECEIVED A PACKET \n", fd);
printf("waiting on port %d\n", myaddr.sin_port);
recvlen = recvfrom(fd, buf, BUFSIZE, 0, (struct sockaddr *)&remaddr, &addrlen);
if (recvlen > 0) {
buf[recvlen] = 0;
printf("received message: \"%s\" (%d bytes)\n", buf, recvlen);
}
else
printf("uh oh - something went wrong!\n");
//sprintf(buf, "ack %d", msgcnt++);
}
if (FD_ISSET(fd2, &readfds)) {
printf("socket %i RECEIVED A PACKET \n", fd2);
printf("waiting on port %d\n", myaddr2.sin_port);
recvlen2 = recvfrom(fd2, buf2, BUFSIZE, 0, (struct sockaddr *)&remaddr2, &addrlen2);
if (recvlen2 > 0) {
buf[recvlen2] = 0;
printf("received message2: \"%s\" (%d bytes)\n", buf2, recvlen2);
}
else
printf("uh oh - something went wrong2!\n");
//sprintf(buf, "ack %d", msgcnt++);
}
}
}
}
result is shown in the picture:
================
Right now i checked the program in ns3 simulator network. It works correctly. so it seems that problem is with loopback. Please guide me how could i make loopback and test it over localhost.

Unable to close server side socket

Following is a single server-client code which are trying to send-receive few buffers, and later close the connection.
Server Code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <string>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <arpa/telnet.h>
#include <unistd.h>
char buff1[][3]= {{0xff , 0xfd, 0x18},{0xff , 0xfd, 0x1e},{0xff , 0xfd, 0x1d}};
char recbuf[1024];
void mwrite (int sock, char * buf, int size)
{
int n = send( sock, buf, size, 0 );
if (n < 0)
{
perror("ERROR writing to socket");
return;
}
}
void read (int sock)
{
char buffer[256];
/* Now read client response */
memset(buffer, 0, sizeof(buffer));
int n = recv( sock, buffer, 255, 0 );
if (n < 0)
{
perror("ERROR reading from socket");
return;
}
for (int i = 0; i < n; i++)
printf("%2x ", buffer[i]);//printing ascii characters
printf("\n");
}
int main(int argc , char *argv[] )
{
int sockfd , newsockfd , portno;
socklen_t clilen;
char buffer[256];
struct sockaddr_in serv_addr, cli_addr;
int n;
sockfd = socket(AF_INET , SOCK_STREAM , 0);
if (sockfd < 0 )
{
perror("Error opening socket ");
exit(1);
}
/* Initialize socket structure */
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);
/* Now bind the host address using client */
if(bind(sockfd, (struct sockaddr *) &serv_addr , sizeof(serv_addr)) <0)
{
perror("Error on binding");
exit(1);
}
if(listen(sockfd,5)<0)
{
perror("Error on listen");
exit(1);
}
int count = 1;
clilen = sizeof(cli_addr);
newsockfd = accept(sockfd,(struct sockaddr *) &cli_addr, &clilen);
if (newsockfd < 0)
{
perror("ERROR on accept");
exit(1);
}
printf("Server Sending (DO TERMINAL TYPE)\n");
while ((n = write(newsockfd,buff1,sizeof(buff1)))>0)
{
printf("Server Sent query %d: %x %x %x\n", count, buff1[count][0], buff1[count][1], buff1[count][2]);
n = read(newsockfd, recbuf , sizeof(recbuf));
printf("Server received responset: %x %x %x\n", recbuf[0], recbuf[1], recbuf[2]);
count++;
count = count % 3;
if(n<0)
{
perror("Error writing to socket ");
exit(1);
}
}
return 0 ;
}
Client Code :
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <string>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <arpa/telnet.h>
#include <unistd.h>
#include <netdb.h>
char buff2[] = {0xff,0xfc,0x18};
void read (int sock)
{
char buffer[256];
/* Now read server response */
memset(buffer, 0, sizeof(buffer));
int n = recv( sock, buffer, 255, 0 );
if (n < 0)
{
perror("ERROR reading from socket");
return;
}
printf("\n%d bytes received buffer is: %s", n, buffer);
}
void mwrite (int sock, char * buf, int size)
{
int n = send( sock, buf, size, 0 );
if (n < 0)
{
perror("ERROR writing to socket");
return;
}
printf("Bytes Sent: %d\n", n);
}
int main(int argc, char *argv[])
{
int sockfd, portno, n;
struct sockaddr_in serv_addr;
struct hostent *server1;
char buffer1[256];
if (argc < 3)
{
fprintf(stderr,"usage %s hostname port\n", argv[0]);
return(0);
}
portno = atoi(argv[2]);
/* Create a socket point */
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
{
perror("ERROR opening socket");
return(1);
}
server1 = gethostbyname(argv[1]);
if (server1 == 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 *)server1->h_addr, (char*)&serv_addr.sin_addr.s_addr, server1->h_length);
serv_addr.sin_port = htons( portno );
/*Connect to server*/
if (connect( sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr) ) < 0)
{
perror("ERROR connecting");
return(1);
}
printf("Recieving Buffer 1 from Server side");
bzero(buffer1,256);
while(true)
{
n= read(sockfd,buffer1,sizeof(buffer1));
if(n<0)
printf("ERROR reading in socket %d len %d", n, sizeof(buffer1));
n= write(sockfd,buff2,sizeof(buff2));
if(n<0)
printf("ERROR writing in socket %d len %d", n, sizeof(buff2));
printf("\nSent Buffer2 (WON'T TERMINAL TYPE) from client side");
}
return 0;
}
Output :
Server Side :
./single_sample 5667
Server Sending (DO TERMINAL TYPE)
Server Sent query 1: ffffffff fffffffd 1e
Server received responset: ffffffff fffffffc 18
Server Sent query 2: ffffffff fffffffd 1d
Server received responset: ffffffff fffffffc 18
Error writing to socket : Connection reset by peer
Client Side:
./sample_client 127.0.0.1 5667
Recieving Buffer 1 from Server side
Sent Buffer2 (WON'T TERMINAL TYPE) from client side
Basically I am trying to close the socket once both the buffers are sent. But getting the above error. I am unable to solve whether the error is occuring from server side or client side.
Also, while running this code on a linux machine how to capture the data bytes sent on wireshark
Thanks in advance.
Your client writes its message and then immediately disconnects, which leads the server to get the Connection reset by peer error - since the client part of the connection no longer exists.

c++ select only checks last client socket

i am writing a server for a chat client i am making
the problem is the following
Select only lifts its block if a net client connects
and if the last connected client is writing.
example:
i have 4 clients connected
the server will keep blocking until client no. 4 writes
if client 1-3 writes it keeps blocking
what am i doing wrong?
for analysing here is my code might contain ugly and useless code
but that's just analysing its behaviour
Server.c++
#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 <boost/thread/thread.hpp>
#include <sys/time.h>
#include <sys/ioctl.h>
using namespace std;
void error(char *msg, int socket) {
perror(msg);
close(socket);
exit(1);
}
int main(int argc, char** argv) {
int sockfd, newsockfd, portno, n, highsock;
socklen_t clilen;
fd_set readfds;
list<int> CliSocks;
FD_ZERO(&readfds);
/*
* Sockfd, newsockfd contain values returned by the socket
* portno stores the port number on which the server accepts connections
* clilen stores the size of the address of the client
* n contains the amount of character written of read
*/
char buffer[256];
/* buffer contains the characters read from the socket*/
struct sockaddr_in serv_addr, cli_addr;
/*
* sockaddr_in contains an internet address
* serv_addr contains the servers address
* cli addr contains the clients address
*/
if (argc < 2) {
fprintf(stderr, "ERROR no port provided");
exit(1);
}
/*
* error if no argument
*/
sockfd = socket(AF_INET, SOCK_STREAM, 0);
highsock = sockfd;
FD_SET(sockfd, &readfds);
int opt = 1;
ioctl(sockfd, FIONBIO, &opt);
if (sockfd < 0) {
error("ERROR opening socket", sockfd);
}
/*
* socket() creates a new socket
* argument 1 contains the address domain
* argument 2 contains the socket type
* argument 3 contains the protocol should be 0
* socket() returns a reference for itself
*/
bzero((char*) &serv_addr, sizeof (serv_addr));
/* empty the serv_addr variable*/
portno = atoi(argv[1]);
/*converts the port argument from string to int*/
serv_addr.sin_family = AF_INET;
/*set the code for the address family*/
serv_addr.sin_port = htons(portno);
/*htons converts the portno to network bytes and gives it to the server address*/
serv_addr.sin_addr.s_addr = INADDR_ANY;
/*set the server ip to the ip of the running machine*/
if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof (serv_addr)) < 0)
error("ERROR on binding", sockfd);
/*
* bind() binds a socket to an address, in this case the
* addess of the current host
*/
listen(sockfd, 5);
/*the listen system call allows the process to listen on the socket for connections*/
while (1) {
int sockcount = select(highsock + 1, &readfds, NULL, NULL, NULL);
clilen = sizeof (cli_addr);
newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen);
/*
* accept() lets the system wait until a client connects to the server
*/
if (newsockfd > 0) {
ioctl(newsockfd, FIONBIO, &opt);
FD_SET(newsockfd, &readfds);
highsock = newsockfd;
CliSocks.push_back(newsockfd);
}
for (list<int>::iterator it = CliSocks.begin(); it != CliSocks.end(); it++) {
bzero(buffer, 256);
n = read(*it, buffer, 255);
if(buffer[0] != 0){
printf("Here is the message: %s", buffer);
/*
* bzero empties the buffer
* read obviously reads data from the new socket descriptor
*/
n = write(*it, "I got your message", 18);
if (n < 0) error("ERROR writing to socket", sockfd);
}
}
}
close(sockfd);
return 0;
}
The problem is that you must reset readfds every time in the loop before the call to select. This is because the call to select modifies its parameters.
while (1) {
FD_ZERO(&readfds);
FD_SET(sockfd, &readfds);
highsock = sockfd;
for (list<int>::iterator it = CliSocks.begin(); it != CliSocks.end(); it++) {
FD_SET(*it, &readfds);
highsock = *it > highsock ? *it : highsock;
}
int sockcount = select(highsock + 1, &readfds, NULL, NULL, NULL);
...
}