I'm trying to create a server that can receive messages from multiple connected clients, but in my code, the recv() function always return -1. How can I make my server receive codes from the client?
This is my server. The recv() function is called in the while loop at the bottom.
I tried to use read(), but I couldn't find a way to make it unblocking. Is there any way to interpret this by using read()? If not, How can I fix this problem with recv() always returning -1, despite I have a new client connected and have a new message sent?
/*------------------Header Files----------------------------------------------------------------------*/
#define _GNU_SOURCE
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<errno.h>
#include<fcntl.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<sys/un.h>
#include<sys/stat.h>
#include<netinet/in.h>
#include<netinet/ip.h>
#include<arpa/inet.h>
/*-------------------Linked List------------------------------------------------------------------------*/
struct client_online{
int client_socket;
char* name;
struct client_online* next;
};
/*-------------------Global Variables-------------------------------------------------------------------*/
struct client_online* first_client = NULL;
/*-------------------Main Function----------------------------------------------------------------------*/
int main(int argc, char* argv[]){
// Cite: get help from office hour code
// Creating the socket
int server_socket;
server_socket = socket(AF_INET, SOCK_STREAM | SOCK_NONBLOCK, 0);
if(server_socket < 0){
perror("Error creating server socket");
return -1;
}
// Server address
struct sockaddr_in server_address;
memset(&server_address, 0, sizeof(struct sockaddr_in));
server_address.sin_family = AF_INET;
server_address.sin_port = htons(atoi(argv[2]));
server_address.sin_addr.s_addr = inet_addr(argv[1]);
// Binding the socket
int binder = bind(server_socket, (const struct sockaddr *) &server_address, sizeof(server_address));
if(binder == -1){
perror("Error calling bind");
return -1;
}
// Listen to the socket
int listener = listen(server_socket, 50);
if(listener == -1){
perror("Error calling listen");
return -1;
}
// Client address
struct sockaddr_in client_address;
// Reading and writing
int quit = 0;
while(!quit){
// Check if there is a new connection
int client_address_size = sizeof(client_address);
int each_client_socket = accept4(server_socket,
(struct sockaddr*) &client_address,
&client_address_size,
SOCK_NONBLOCK);
// If there is a new connection, add client to linked list
if(each_client_socket >= 0){
if(first_client == NULL){
first_client = malloc(sizeof(*first_client));
first_client->client_socket = each_client_socket;
first_client->name = (char*)malloc(100);
strcpy(first_client->name,"User");
first_client->next = NULL;
free(first_client->name);
free(first_client);
}
else{
struct client_online* tracker = first_client;
while(tracker->next != NULL){
tracker = tracker->next;
}
struct client_online* new_client;
new_client = malloc(sizeof(*new_client));
new_client->client_socket = each_client_socket;
new_client->name = (char*)malloc(100);
strcpy(new_client->name, "User");
new_client->next = NULL;
tracker->next = new_client;
free(new_client->name);
free(new_client);
}
}
// Check if there are messages recieved
struct client_online* checker = first_client;
while(checker != NULL){
char client_response[256];
char toSend[256];
bzero(client_response, sizeof(client_response));
int receiver = recv(checker->client_socket,
client_response,
sizeof(client_response),
MSG_DONTWAIT);
printf("%d\n", receiver);
if(receiver > 0){
printf("message received\n");
snprintf(toSend, sizeof(toSend), "%s: %s\n", checker->name, client_response);
struct client_online* sender = first_client;
while(sender != NULL){
send(sender->client_socket, toSend, sizeof(toSend), MSG_DONTWAIT);
}
}
checker = checker->next;
}
sleep(1);
}
return 0;
}
Here is my client
/*----------------------------------------------------Header Files----------------------------------------*/
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<fcntl.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<sys/un.h>
#include<sys/stat.h>
#include<netinet/ip.h>
#include<arpa/inet.h>
#define _GNU_SOURCE
/*----------------------------------------------------Main Function--------------------------------------*/
int main(int argc, char* argv[]){
// Seek help from office hour codes
// Create the client socket
int client_socket = socket(AF_INET, SOCK_STREAM, 0);
if(client_socket < 0){
perror("Error creating client socket");
return -1;
}
// Construct the address of the connection
struct sockaddr_in client_address;
memset(&client_address, 0, sizeof(struct sockaddr_in));
client_address.sin_family = AF_INET;
client_address.sin_port = htons(atoi(argv[2]));
client_address.sin_addr.s_addr = inet_addr(argv[1]);
// Connect the client to the server
int connecter = connect(client_socket,
(const struct sockaddr*) &client_address,
sizeof(struct sockaddr_in));
if(connecter < 0){
perror("Error connecting to server");
}
// Reading and writing
int quit = 0;
while(!quit){
// Read from command line
char client_message[256];
memset(&client_message, 0, sizeof(client_message));
int flags = fcntl(STDIN_FILENO, F_GETFL, 0);
fcntl(STDIN_FILENO, F_SETFL, flags | O_NONBLOCK);
int reader = read(STDIN_FILENO, client_message, sizeof(client_message));
if (reader > 0) {
// Writing normal message
send(client_socket, client_message, 1, MSG_WAITALL);
}
//
sleep(1);
}
return 0;
}
Since you are passing MSG_DONTWAIT to your recv call, if there is nothing to receive from the client yet, the call will return an error to indicate that fact.
If you are using polling mechanism, like epoll, then you would typically wait for a readable notification. Once the notification is received, you can retry the recv call. I don't see any use of a polling mechanism in your code.
Alternatively, you can spawn a thread for each new connection, and use blocking calls to recv (omit the MSG_DONTWAIT flag).
Related
I am pretty new to socket programming and the C language. I want to teleoperate a robot over the internet for that I have to send some values to a robot computer. Here is my code...
x = state.position_val[0];
y = state.position_val[1];
z = state.position_val[2];
Rx = state.gimbal_joints[0]*1000;
Ry= state.gimbal_joints[1]*1000;
Rz = state.gimbal_joints[2]*1000;
double arr[7] = { x, y, z, Rx, Ry, Rz, btonn };
SAFEARRAY* psa = SafeArrayCreateVector(VT_R8, 0, 7);
void* data;
SafeArrayAccessData(psa, &data);
CopyMemory(data, arr, sizeof(arr));
SafeArrayUnaccessData(psa);
return psa;
These are the code snippets under the while loop at each loop this code gets the state value of the robot and creates an array that is further used for teleoperation. I need to send this array over the internet to another computer.
Please help me how to do this?
I have tested this on Windows machine
Go to https://ngrok.com create an account
your robot should run ngrok client use following commands
ngrok authtoken xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
ngrok tcp 80
Forwarding tcp://3.tcp.ngrok.io:15842 -> localhost:80
Here ngrok will assign a local PORT to 80 and random port to outside network ie Interner exposed port. You have to add 80 and that port to your firewall rules of robot network device).
Goto https://whatismyipaddress.com/hostname-ip here put 3.tcp.ngrok.io Look IP address box from ngrok console out. You will get your robot's global IP. that you can connect to your robot from anywhere in the world.
Following are the Client and Server examples that you can compile and run.
gcc .\Client.c -o Client
gcc .\Server.c -o Server
Client.c
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/socket.h>
#include<arpa/inet.h>
#include<unistd.h>
//Create a Socket for server communication
short SocketCreate(void)
{
short hSocket;
printf("Create the socket\n");
hSocket = socket(AF_INET, SOCK_STREAM, 0);
return hSocket;
}
//try to connect with server
int SocketConnect(int hSocket)
{
int iRetval=-1;
int ServerPort = 15842; // ngroks external tcp port
struct sockaddr_in remote= {0};
remote.sin_addr.s_addr = inet_addr("3.134.xxx.xxx"); //Robot IP
remote.sin_family = AF_INET;
remote.sin_port = htons(ServerPort);
iRetval = connect(hSocket,(struct sockaddr *)&remote,sizeof(struct sockaddr_in));
return iRetval;
}
// Send the data to the server and set the timeout of 20 seconds
int SocketSend(int hSocket,char* Rqst,short lenRqst)
{
int shortRetval = -1;
struct timeval tv;
tv.tv_sec = 20; /* 20 Secs Timeout */
tv.tv_usec = 0;
if(setsockopt(hSocket,SOL_SOCKET,SO_SNDTIMEO,(char *)&tv,sizeof(tv)) < 0)
{
printf("Time Out\n");
return -1;
}
shortRetval = send(hSocket, Rqst, lenRqst, 0);
return shortRetval;
}
//receive the data from the server
int SocketReceive(int hSocket,char* Rsp,short RvcSize)
{
int shortRetval = -1;
struct timeval tv;
tv.tv_sec = 20; /* 20 Secs Timeout */
tv.tv_usec = 0;
if(setsockopt(hSocket, SOL_SOCKET, SO_RCVTIMEO,(char *)&tv,sizeof(tv)) < 0)
{
printf("Time Out\n");
return -1;
}
shortRetval = recv(hSocket, Rsp, RvcSize, 0);
printf("Response %s\n",Rsp);
return shortRetval;
}
//main driver program
int main(int argc, char *argv[])
{
int hSocket, read_size;
struct sockaddr_in server;
char SendToServer[100] = {0};
char server_reply[200] = {0};
//Create socket
hSocket = SocketCreate();
if(hSocket == -1)
{
printf("Could not create socket\n");
return 1;
}
printf("Socket is created\n");
//Connect to remote server
if (SocketConnect(hSocket) < 0)
{
perror("connect failed.\n");
return 1;
}
printf("Sucessfully conected with server\n");
printf("Enter the Message: ");
gets(SendToServer);
//Send data to the server
SocketSend(hSocket, SendToServer, strlen(SendToServer));
//Received the data from the server
read_size = SocketReceive(hSocket, server_reply, 200);
printf("Server Response : %s\n\n",server_reply);
close(hSocket);
shutdown(hSocket,0);
shutdown(hSocket,1);
shutdown(hSocket,2);
return 0;
}
Server.c
#include<stdio.h>
#include<string.h>
#include<sys/socket.h>
#include<arpa/inet.h>
#include<unistd.h>
short SocketCreate(void)
{
short hSocket;
printf("Create the socket\n");
hSocket = socket(AF_INET, SOCK_STREAM, 0);
return hSocket;
}
int BindCreatedSocket(int hSocket)
{
int iRetval=-1;
int ClientPort = 80; //Robot local port
struct sockaddr_in remote= {0};
/* Internet address family */
remote.sin_family = AF_INET;
/* Any incoming interface */
remote.sin_addr.s_addr = htonl(INADDR_ANY);
remote.sin_port = htons(ClientPort); /* Local port */
iRetval = bind(hSocket,(struct sockaddr *)&remote,sizeof(remote));
return iRetval;
}
int main(int argc, char *argv[])
{
int socket_desc, sock, clientLen, read_size;
struct sockaddr_in server, client;
char client_message[200]= {0};
char message[100] = {0};
const char *pMessage = "hello aticleworld.com";
//Create socket
socket_desc = SocketCreate();
if (socket_desc == -1)
{
printf("Could not create socket");
return 1;
}
printf("Socket created\n");
//Bind
if( BindCreatedSocket(socket_desc) < 0)
{
//print the error message
perror("bind failed.");
return 1;
}
printf("bind done\n");
//Listen
listen(socket_desc, 3);
//Accept and incoming connection
while(1)
{
printf("Waiting for incoming connections...\n");
clientLen = sizeof(struct sockaddr_in);
//accept connection from an incoming client
sock = accept(socket_desc,(struct sockaddr *)&client,(socklen_t*)&clientLen);
if (sock < 0)
{
perror("accept failed");
return 1;
}
printf("Connection accepted\n");
memset(client_message, '\0', sizeof client_message);
memset(message, '\0', sizeof message);
//Receive a reply from the client
if( recv(sock, client_message, 200, 0) < 0)
{
printf("recv failed");
break;
}
printf("Client reply : %s\n",client_message);
if(strcmp(pMessage,client_message)==0)
{
strcpy(message,"Hi there !");
}
else
{
strcpy(message,"Invalid Message !");
}
// Send some data
if( send(sock, message, strlen(message), 0) < 0)
{
printf("Send failed");
return 1;
}
close(sock);
sleep(1);
}
return 0;
}
You can now send receive data between robot and your computer
I'm new in socket programming.
My program creates two clients that write to a server, this server reads data using threads and then prints them. I would like to send all this data to another client when it makes a request. Have I to create another socket or is it possible to use the same used before?
Here is my code.
Thanks.
Server.c
#include<stdio.h>
#include<stdlib.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<string.h>
#include <arpa/inet.h>
#include <fcntl.h> // for open
#include <unistd.h> // for close
#include<pthread.h>
struct message { //dichiarazione struct
time_t timestamp;
char g; //process identifier
int x;
};
struct message client_message[10000];
int q=0;
static void * socketThread(void *arg)
{
int newSocket = *((int *)arg);
while(read(newSocket , &client_message[q] , sizeof(client_message))!=0) {
printf("message %d %d %ld\n",client_message[q].x,client_message[q].g,client_message[q].timestamp);
fflush(stdout);
sleep(1);
q++;
}
pthread_exit(NULL);
}
int main(){
int serverSocket, newSocket;
struct sockaddr_in serverAddr;
struct sockaddr_storage serverStorage;
socklen_t addr_size;
//Create the socket.
serverSocket = socket(AF_UNIX, SOCK_STREAM, 0);
// Configure settings of the server address struct
// Address family = Internet
serverAddr.sin_family = AF_UNIX;
//Set port number, using htons function to use proper byte order
serverAddr.sin_port = htons(55555);
//Set IP address to localhost
serverAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
//INADDR_ANY;
//Set all bits of the padding field to 0
memset(serverAddr.sin_zero, '\0', sizeof serverAddr.sin_zero);
//Bind the address struct to the socket
bind(serverSocket, (struct sockaddr *) &serverAddr, sizeof(serverAddr));
//Listen on the socket, with 40 max connection requests queued
if(listen(serverSocket,50)==0)
printf("Listening\n");
else
printf("Error\n");
pthread_t tid[2];
int i = 0;
while(i<2)
{
//Accept call creates a new socket for the incoming connection
addr_size = sizeof serverStorage;
newSocket = accept(serverSocket, (struct sockaddr *) &serverStorage, &addr_size);
//for each client request creates a thread and assign the client request to it to process
//so the main thread can entertain next request
if( pthread_create(&tid[i], NULL, socketThread, &newSocket) != 0 )
printf("Failed to create thread\n");
i++;
}
pthread_join(tid[1], NULL);
pthread_join(tid[0], NULL);
for(i=0;i<50;i++){
printf("%d aaa %d\n",client_message[i].x,client_message[i].g);
}
close(newSocket);
return 0;
}
I am writing a simple tcp echo client server code both my client and server code are running on the same machine i did bind two different addresses to client and server but client ip address is not getting printed when connected to server i changed addresses and still i was not able to print address i don't see any mistake in code.Is this my os issue or am i making some mistake.
my server code:
#include<stdio.h>
#include<stdlib.h>
#include<sys/socket.h>
#include<sys/types.h>
#include<string.h>
#include<netinet/in.h>
#define ERROR -1
#define MAX_CLIENTS 10
#define MAX_DATA 1024
int main(int argc, char *argv[]){
struct sockaddr_in server;
struct sockaddr_in client;
int sock;
int new;
int sockaddr_len = sizeof(struct sockaddr_in);
int data_len;
char data[MAX_DATA+1];
if((sock = socket(AF_INET,SOCK_STREAM,0)) == ERROR){
perror("server socket");
exit(-1);
}
server.sin_family = AF_INET;
server.sin_port = htons(atoi(argv[1]));
inet_aton(argv[2],&server.sin_addr.s_addr);
bzero(&server.sin_zero,0);
if(bind(sock, (struct sockaddr *)&server,sockaddr_len) == ERROR){
perror("bind");
exit(-1);
}
if(listen(sock, MAX_CLIENTS) == ERROR){
perror("listen");
exit(-1);
}
while(1){
if((new = accept(sock,(struct sockaddr *)&client,&sockaddr_len)) == ERROR){
perror("accept");
exit(-1);
}
//ip not getting printed
printf("New client connected from port no %d IP %s\n",ntohs(client.sin_port),inet_ntoa(client.sin_addr.s_addr));
data_len = 1;
while(data_len){
data_len = recv(new,data,MAX_DATA,0);
if(data_len){
send(new, data, data_len,0);
data[data_len] = '\0';
printf("Sent message: %s", data);
}
}
printf("Client disconnected\n");
close(new);
}
}
my client code:
#include<stdio.h>
#include<stdlib.h>
#include<sys/socket.h>
#include<sys/types.h>
#include<string.h>
#include<netinet/in.h>
#define ERROR -1
#define BUFFER 1024
int main(int argc, char *argv[]){
struct sockaddr_in remote_server,client;
int sock,len;
char input[BUFFER];
char output[BUFFER+1];
client.sin_family = AF_INET;
client.sin_port = htons(3000);
inet_aton("127.0.2.8",&client.sin_addr.s_addr);
bzero(&client.sin_zero,0);
if((sock = socket(AF_INET,SOCK_STREAM,0)) == ERROR){
perror("socket");
exit(-1);
}
int size = sizeof(struct sockaddr_in);
if(bind(sock, (struct sockaddr *)&client,size) == ERROR){
perror("bind");
exit(-1);
}
remote_server.sin_family = AF_INET;
remote_server.sin_port = htons(atoi(argv[2]));
remote_server.sin_addr.s_addr = inet_addr(argv[1]);
bzero(&remote_server.sin_zero , 0);
if((connect(sock ,(struct sockaddr *)&remote_server , sizeof(struct sockaddr_in))) == ERROR){
perror("connect");
exit(-1);
}
while(1){
fgets(input, BUFFER, stdin);
send(sock, input, strlen(input) , 0);
len = recv(sock,output,BUFFER,0);
output[len] = '\0';
printf("%s\n",output);
}
close(sock);
}
This is the output:
New client connected from port no 3000 and IP
First of all you need two more includes in client as well as server
#include<arpa/inet.h> // for inet_aton(), inet_addr() and inet_ntoa()
#include<unistd.h> //for close()
Secondly,
The function declaration for inet_aton() and inet_ntoa() are respectively:
int inet_aton(const char *cp, struct in_addr *inp);
and
char *inet_ntoa(struct in_addr in);
So, You must pass the entire structure i.e xyzaddr.sin_addr instead of xyzaddr.sin_addr.s_addr(which is an int)
Hence make these changes as well:
In server:
inet_aton(argv[2],&server.sin_addr.s_addr); -> inet_aton(argv[2],&server.sin_addr);
inet_ntoa(client.sin_addr.s_addr) -> inet_ntoa(client.sin_addr)
In client:
inet_aton("127.0.2.8",&client.sin_addr.s_addr); -> inet_aton("127.0.2.8",&client.sin_addr);
I have made the following chat server program in c. The Problem is that as soon as I run my client and 'Client Says :-' is displayed on the Client Screen, the server immediately displays 'Client Says :-', 'Server Says :-' without waiting for the Client to give the input and then process it and the program doesnot work after that no matter what I input.
I want my Client to ask for input then send it to server , The server should then display the Client's input and ask for it's own input. This should go on until anyone of them enters 'bye'.
//Chat Server
#include<stdio.h>
#include<stdlib.h>
#include<sys/socket.h>
#include<sys/types.h>
#include<netinet/in.h>
#include<string.h>
#include<errno.h>
int main()
{
int sockfd = socket(AF_INET,SOCK_STREAM,0);
if(sockfd<0)
{
perror("Error in Creating Socket\n");
exit(-1);
}
struct sockaddr_in server,client;
bzero(&server,sizeof(server));
server.sin_family = AF_INET;
server.sin_port = htons(10000);
server.sin_addr.s_addr = INADDR_ANY;
if(bind(sockfd, (struct sockaddr*)&server, sizeof(server))<0)
{
perror("Error in Socket Binding\n");
exit(-1);
}
if(listen(sockfd,5)<0)
{
perror("Error in Listening\n");
exit(-1);
}
printf("Listening\n");
char clientsent[500];
char bhago[5] = "exit";
bhago[5] = '\0';
char serverinput[500];
while(1)
{
int acceptfd = accept(sockfd, (struct sockaddr*)&client, (socklen_t*)sizeof(client));
pid_t pid = fork();
if(pid == 0)//child process is executing
{
close(sockfd);
while(1)
{
bzero(&serverinput, 500);
bzero(&clientsent, 500);
int n = recv(acceptfd, clientsent,500,0);
printf("Client Says :-\n");
printf("%s",clientsent);
if(strcmp(clientsent,bhago) == 0)
{
close(acceptfd);
exit(0);
}
printf("Server Says :-\n");
int x = 0;
do{
serverinput[x]=getchar();
x++;
}while(x-1 != '\n');
send(acceptfd, serverinput, 500, 0);
if(strcmp(serverinput,bhago) == 0)
{
close(acceptfd);
exit(0);
}
}
}
close(acceptfd);
}
}
//Chat Client
#include<stdio.h>
#include<stdlib.h>
#include<sys/socket.h>
#include<sys/types.h>
#include<netinet/in.h>
#include<string.h>
#include<errno.h>
int main()
{
int sockfd = socket(AF_INET,SOCK_STREAM,0);
if(sockfd<0)
{
perror("Error in Creating Socket\n");
exit(-1);
}
struct sockaddr_in server;
bzero(&server,sizeof(server));
server.sin_family = AF_INET;
server.sin_port = htons(10000);
server.sin_addr.s_addr = INADDR_ANY;
if(connect(sockfd, (struct sockaddr*)&server, sizeof(server))<0)
{
perror("Error in Connection\n");
exit(-1);
}
printf("Connection Established\n");
char clientinput[500];
char bhago[5] = "exit";
bhago[5] = '\0';
char serversent[500];
while(1)
{
bzero(&clientinput, 500);
bzero(&serversent, 500);
printf("Client Says :-\n");
int x = 0;
do{
clientinput[x]=getchar();
x++;
}while(x-1 != '\n');
send(sockfd, clientinput, 500, 0);
if(strcmp(clientinput, bhago) == 0)
{
close(sockfd);
exit(0);
}
printf("Server Said :-\n");
recv(sockfd, serversent, 500,0);
printf("%s",serversent);
if(strcmp(serversent, bhago) == 0)
{
close(sockfd);
exit(0);
}
}
close(sockfd);
}//main
For starters, the latter of those two lines
char bhago[5] = "exit";
bhago[5] = '\0';
invokes undefined behaviour by writing out of bhago's bounds by accessing the 6th element, with bhago being 5 elements wide. From now on anything can happen.
In C arrays' indexes are 0-based. The 1st element here is bhago[0].
And this
..., (socklen_t*)sizeof(client));
is plain horrible wrong. Do not blindly cast away compilation errors. A pointer is expected and the code passes a compile-time constant, invoking undefined behaviour again here. I'd expect the code to die with execution of this line immediately.
accept() expects a socklen_t * as last parameter, so pass one:
socklen_t socklen = sizeof client;
..., &socklen));
// A simple echo server
// ./server port_no
#include<stdio.h>
#include<stdlib.h>
#include<sys/socket.h>
#include<sys/types.h>
#include<netinet/in.h>
#include<error.h>
#include<strings.h>
#include<unistd.h>
#include<arpa/inet.h>
#define ERROR -1
#define MAX_CLIENTS 2
#define MAX_DATA 1024
main(int argc, char **argv)
{
struct sockaddr_in server;
struct sockaddr_in client;
int sock;
int new;
int sockaddr_len = sizeof(struct sockaddr_in);
int data_len;
char data[MAX_DATA];
if((sock = socket(AF_INET , SOCK_STREAM, 0)) == ERROR)
{
perror("server socket: ");
exit(-1);
}
server.sin_family = AF_INET;
server.sin_port = htons(atoi(argv[1]));
server.sin_addr.s_addr = INADDR_ANY;
bzero(&server.sin_zero,8);
if((bind(sock , (struct sockaddr *)&server, sockaddr_len)) == ERROR)
{
perror("bind : ");
exit(-1);
}
if((listen(sock, MAX_CLIENTS)) == ERROR)
{
perror("listen");
exit(-1);
}
while(1) //Better signal handling required
{
if((new == accept(sock, ( struct sockaddr *)&client , &sockaddr_len)) == ERROR)
{
perror("accept");
exit(-1);
}
printf("New Client connected from port no %d and IP %s\n",ntohs(client.sin_port),inet_ntoa(client.sin_addr));
data_len = 1;
while(data_len)
{
data_len = recv(new,data , MAX_DATA, 0);
if(data_len)
{
send(new, data, data_len, 0);
data[data_len] = '\0' ; // null the last byte to detect string
printf("Sent mesg: %s", data);
}
}
printf("Client disconnected\n");
close(new);
}
close(sock);
}
HI i have been learning socket programming in C . And recently i had written a code for tcp echo server. Server does shows connected when i use netstat command but as soon as i run the code using telnet it starts printing infinite messages instead of waiting for me to write a message in other terminal. Please help me figure out where i am i going wrong.
The reason for the infinite loop is the code
f((new == accept(sock, ( struct sockaddr *)&client , &sockaddr_len)) == ERROR)
It should instead be
f((new = accept(sock, ( struct sockaddr *)&client , &sockaddr_len)) == ERROR)
It's == vs =. With ==, the socket returned by accept() is never assigned to new, so calling recv() on it returns -1 (error in this case), and because the code doesn't check for the error, as pointed out Alan Au, the result is an infinite loop.
BTW, if you watch the compiler warnings or enable more warnings by using a switch, e.g. -Wall with gcc, you can usually get some good insight into possible issues with the code.