/* Server Code */
#include<stdio.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<sys/socket.h>
#include<sys/types.h>
#include<netinet/in.h>
#include<pthread.h>
#define MAXSIZE 50
void transmit();
void Recieve();
int sockfd, newsockfd, retval;
socklen_t actuallen;
int recedbytes, sentbytes;
struct sockaddr_in serveraddr, clientaddr;
// char buff[MAXSIZE];
int a = 0, port_no;
main()
{
printf("Enter port number: ");
scanf("%d",&port_no);
sockfd=socket(AF_INET,SOCK_STREAM,0);
if(sockfd==-1) {
printf("\nSocket creation error");
exit(-1);
}
serveraddr.sin_family=AF_INET;
serveraddr.sin_port=htons(port_no);
serveraddr.sin_addr.s_addr=htonl(INADDR_ANY);
retval= bind(sockfd, (struct sockaddr*)&serveraddr, sizeof(serveraddr));
if(retval == -1) {
printf("Binding error");
close(sockfd);
exit(0);
}
retval = listen(sockfd, 1);
if (retval == -1) {
close(sockfd);
exit(0);
}
actuallen = sizeof(clientaddr);
newsockfd = accept(sockfd, (struct sockaddr*)&clientaddr, &actuallen);
if(newsockfd == -1) {
close(sockfd);
exit(0);
}
int i=1;
pid_t pid = fork();
if(pid == 0)
transmit();
else
Recieve();
close(newsockfd);
close(sockfd);
}
void Recieve()
{
char buff[50]; int f=1;
while(f)
{
recedbytes=recv(newsockfd,buff,sizeof(buff),0);
if(recedbytes == -1) {
close(sockfd);
close(newsockfd);
exit(0);
}
printf("recdbytes: %d\n", recedbytes);
if(strcmp(buff, "Stop") == 0)
{
puts("Closing");
strcpy(buff,"Stop");
sentbytes=send(newsockfd,buff,sizeof(buff),0);
if(sentbytes == -1) {
close(sockfd);
close(newsockfd);
exit(0);
}
f=0;
}
else {
char cl[]="Client: ";
strcat(cl,buff);
puts(cl);
}
}
}
void transmit()
{
char buff[50];
while(1)
{
// printf("%s","You: ");
gets(buff);
sentbytes = send(newsockfd, buff, sizeof(buff), 0);
if(sentbytes == -1) {
close(sockfd);
close(newsockfd);
exit(0);
}
}
}
/* Client Code */
#include<stdio.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<sys/socket.h>
#include<sys/types.h>
#include<netinet/in.h>
#include<pthread.h>
#define MAXSIZE 50
void transmit();
void Recieve();
int sockfd, retval;
int recedbytes, sentbytes;
struct sockaddr_in serveraddr;
// char buff[MAXSIZE];
main()
{
int port_no;
printf("Enter port number:");
scanf("%d",&port_no);
sockfd=socket(AF_INET,SOCK_STREAM,0);
if(sockfd == -1) {
printf("\nSocket creation error");
exit(-1);
}
serveraddr.sin_family = AF_INET;
serveraddr.sin_port = htons(port_no);
serveraddr.sin_addr.s_addr = inet_addr("127.0.0.1");
retval = connect(sockfd, (struct sockaddr*)&serveraddr, sizeof(serveraddr));
if(retval == -1) {
printf("Connection error"); close(sockfd);
exit(0);
}
int i = 1;
pid_t pid = fork();
if(pid == 0)
transmit();
else
Recieve();
printf("\n");
close(sockfd);
}
void Recieve()
{
char buff[50];
int f=1;
while(f)
{
recedbytes = recv(sockfd, buff, sizeof(buff), 0);
if(recedbytes == -1) {
close(sockfd);
exit(0);
}
printf("recdbytes: %d\n",recedbytes);
if(strcmp(buff, "Stop") == 0)
{
puts("Closing");
f = 0;
strcpy(buff, "Stop");
sentbytes = send(sockfd, buff, sizeof(buff), 0);
if(sentbytes == -1) {
close(sockfd);
exit(0);
}
}
else {
char sr[] = "Server :";
strcat(sr, buff);
puts(sr);
}
}
}
void transmit()
{
char buff[50];
while(1)
{
// printf("%s","You: ");
gets(buff);
sentbytes = send(sockfd, buff, sizeof(buff), 0);
if(sentbytes == -1) {
close(sockfd);
exit(0);
}
}
}
I am trying to create a chat server/client program using TCP/IP and process creation in C (linux).
It seems like the gets(buff) in transmit function of both the Client and Server Programs is not functioning as blocking and send(..) function is transmitting an empty buff.
As a result, "Client:" or "Server:" in server program and client program respectively is being printed even if no data has actually been sent from the counterpart program.
recedbytes=recv(newsockfd,buff,sizeof(buff),0);
if(recedbytes == -1) {
close(sockfd);
close(newsockfd);
exit(0);
}
printf("recdbytes: %d\n", recedbytes);
if(strcmp(buff, "Stop") == 0)
How are you expecting strcmp to know the length of the received string? You never did anything with recedbytes.
You also have numerous other bugs. You are expecting recv to somehow receive messages, despite the fact that you've never implemented any message protocol.
If you want to send and receive messages, you have to do three things:
Precisely define what a "message" is.
Write code to send a message.
Write code to receive a message.
There's no evidence in the code you've done any of these things. If your definition of a message is "precisely 50 bytes, always including a zero byte that marks the end of the data the receiver should process", then you may be okay on 1 and 2, but you definitely haven't done 3.
Related
/* Server.c */
#include<stdio.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<unistd.h>
#include<signal.h>
#include <string.h>
#define SERV_TCP_PORT 25000
#define BUFSIZE 1024
void login(char *buffer, int i, int j, int sockfd, fd_set master, int fdmax);
void login(char *buffer, int i, int j, int sockfd, fd_set master, int fdmax){
char user[BUFSIZE] = "user", pass[BUFSIZE] = "12345";
char username[BUFSIZE], password[BUFSIZE];
recv(i, username, BUFSIZE, 0);
for (j = 0; j <= fdmax; j++) {
if (FD_ISSET(j, &master)) {
if (j != sockfd && j== i) { // to itself but not all
if (j!=sockfd) {
printf("Username receive [%s] from socket [ %d ]\n", username, i);
if(strcmp(username, user)==0)
{
send(j, username, BUFSIZE, 0);
printf("\nSend the username [ %s ] via socket [%d]\n", username, j);
//bzero(buffer, BUFSIZE);
recv(i, password, BUFSIZE, 0);
for (j = 0; j <= fdmax; j++) {
if (FD_ISSET(j, &master)) {
if (j != sockfd && j== i) { // to itself but not all
if (j!=sockfd) {
printf("Password [%s] from socket [ %d ]\n", password, i);
if(strcmp(password, pass)==0)
{
send(j, password, BUFSIZE, 0);
printf("\nSend the password [ %s ] via socket [%d]\n", password, j);
}
}
}
}
}
}
}
}
}
}
}
int main(int argc, char** argv){
fd_set master;
fd_set read_fds;
struct sockaddr_in myaddr;
struct sockaddr_in remoteaddr;
int fdmax;
int sockfd;
int new_sockfd;
char buffer[BUFSIZE];
int nbytes;
int yes = 1;
int addrlen;
int i, j;
pid_t pid;
sigset_t set1;
sigemptyset(&set1);
sigaddset(&set1, SIGTSTP); //ctrl+z
sigprocmask(SIG_BLOCK, &set1, NULL);
FD_ZERO(&master);
FD_ZERO(&read_fds);
if( (sockfd = socket(AF_INET, SOCK_STREAM, 0) ) == -1){
printf("\nsocket() error!!!\n");
exit(1);}
if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1){
printf("\nSetsockopt() error!!!\n");
exit(1);}
bzero( (char *)&myaddr, sizeof(myaddr) );
myaddr.sin_family = AF_INET;
myaddr.sin_addr.s_addr = INADDR_ANY;
myaddr.sin_port = htons(SERV_TCP_PORT);
bzero(&(myaddr.sin_zero), 8);
if (bind(sockfd, (struct sockaddr *)&myaddr, sizeof(myaddr)) == -1){
printf("\nbind() error!!!\n");
exit(1);}
if (listen(sockfd, 10) == -1){
printf("\nlisten() error!!!\n");
exit(1);}
FD_SET(sockfd, &master);
fdmax = sockfd; // only sockfd at this moment
for(;;){
read_fds = master;
if (pselect(fdmax+1, &read_fds, NULL, NULL, NULL, &set1) == -1){
printf("\nselect() error!!!\n");
exit(1); }
for(i=0; i<=fdmax; i++) {
if( FD_ISSET(i, &read_fds) ){
if (i == sockfd) {
addrlen = sizeof(remoteaddr);
if( (new_sockfd = accept(sockfd, &remoteaddr, &addrlen) ) == -1 ) {
printf("\naccept() error!!!\n");}
else {
FD_SET(new_sockfd, &master);
if(new_sockfd > fdmax){
fdmax = new_sockfd;}
printf("selectserver: new connection from %s on socket %d \n", inet_ntoa(remoteaddr.sin_addr), new_sockfd);
} // esle for accept()
} // else for i==sockfd
else
{ // if i != sockfd
if (nbytes = recv(i, buffer, sizeof(buffer), 0) <=0) {
if (nbytes == 0) {
printf("selectserver: socket %d hung up\n", i); }
else{
printf("\nrecv() error!!!\n"); } // else for nbytes == 0
close(i);
FD_CLR(i, &master); } // for recv
else{
for (j = 0; j <= fdmax; j++)
{
if (FD_ISSET(j, &master)) {
if (j != sockfd && j == i) { // to itself but not all
if (j!=sockfd)
{
printf("Message [ %s ] from socket [ %d ] client [ %s ] \n", buffer, i, inet_ntoa(remoteaddr.sin_addr) );
if(strcmp(buffer, "start")==0){
//printf("Message [%s] from socket [ %d ] client [ %s ] \n", buffer, i, inet_ntoa(remoteaddr.sin_addr) );
send(j, buffer, BUFSIZE, 0);
login(buffer, i, j, sockfd, master, fdmax);
}
else if(strcmp(buffer, "exit")==0){
printf("\nrecv() error!!!\n");
close(i);
FD_CLR(i, &master);
//break;
}
}
}
}
}
}
}
}
}
}
return 0;
}
This is server.c
/* Client.c */
#include<stdio.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<unistd.h>
#include<string.h>
#define SERV_TCP_PORT 25000
#define BUFSIZE 1024
int main(int argc, char *argv[])
{
int sockfd;
char buffer[BUFSIZE+1];
struct sockaddr_in serv_addr;
bzero((char *)&serv_addr, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(SERV_TCP_PORT);
inet_pton(AF_INET, argv[1], &serv_addr.sin_addr);
if( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0){
perror("\nsocket() error!!!\n");
}
if( (connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr) )) < 0){
perror("\nconnect() error!!!\n");
}
printf("\nconnection with server: %s...\n", inet_ntoa(serv_addr.sin_addr));
do
{
bzero(buffer, BUFSIZE);
printf("\nEnter a message : [type /q to quit]");
scanf("%s", buffer);
printf("\nMessage [ %s ] send to server \n", buffer);
send(sockfd, buffer, BUFSIZE, 0);
bzero(buffer, sizeof(buffer));
recv(sockfd, buffer, BUFSIZE, 0);
printf("\nMessage [ %s ] received from server \n", buffer);
} while (strcmp(buffer, "/q"));
close(sockfd);
}
This is client.c
I want to solve the problem with Server.c, but it can't handle multiple clients simultaneously. When I am trying to take input from second client, it hang. The second client begins working after first client done his job.
I see several errors in the code.
When I compile server.c, I get this warning from clang:
server.c:128:32: warning: using the result of an assignment as a condition without parentheses [-Wparentheses]
if (nbytes = recv(i, buffer, sizeof(buffer), 0) <=0) {
I think you intended this instead:
if ((nbytes = recv(i, buffer, sizeof(buffer), 0)) <=0)
Also on line 137 you have this:
if (FD_ISSET(j, &master)) {
... but master doesn't contain the results of your latest pselect() operation, so you probably wanted to do this instead:
if (FD_ISSET(j, &read_fds)) {
Once I corrected those two problems, I could connect to your server with telnet localhost 25000 and get reasonable behavior from it.
However, connecting with your client program resulted in only the first entered line of text being received. That is because your client blocks inside recv(sockfd, buffer, BUFSIZE, 0), and therefore will not process any further lines of text entered into stdin until after it has received some data from the server. If that's intentional behavior, then it's okay, but if you were intending for the clients to be able to send data to the server whenever the user enters text into stdin, you should probably update your client program to use select() in a way similar to how your server does. (On POSIX OS's [not Windows], you can have select() monitor STDIN_FILENO and treat stdin as if it was any other file-descriptor)
I am new to socket programming. I wrote codes for UDP Client and Server which work fine on my computer. I want to run these programs on two different hosts, i.e. the Server on my computer and Client on my friend' computer. How do I do it without a router? Please mention if any specific changes are to be made in the code for the purpose.
Here's the code:
Receiver
#include<stdio.h>
#include<stdlib.h>
#include<sys/socket.h>
#include<sys/types.h>
#include<netinet/in.h>
#include<netinet/ip.h>
#include<string.h>
#include<unistd.h>
int main() {
int ret = socket(AF_INET, SOCK_DGRAM, 0);
if (ret == -1) {
printf("socket creation fails\n");
exit(0);
} else
printf("socket creation succeeds\n");
struct sockaddr_in sender;
int port;
printf("Enter port:");
scanf("%d", & port);
sender.sin_family = AF_INET;
sender.sin_port = htons(port);
sender.sin_addr.s_addr = INADDR_ANY;
int ret1;
ret1 = bind(ret, (struct sockaddr * ) & sender, sizeof(sender));
if (ret1 == -1) {
printf("socket binding fails\n");
exit(0);
}
printf("socket binding succeeds\n");
struct sockaddr_in receiver;
char str[15], str2[15];
int addrlen = sizeof(receiver);
while (1) {
int rec = recvfrom(ret, str, sizeof(str), 0, (struct sockaddr * ) & receiver, & addrlen);
printf("Received:");
str[rec] = '\0';
if (strcmp(str, "exit") == 0)
break;
if (rec == -1) {
printf("recvfrom fails\n");
exit(0);
}
printf("%s\n", str);
printf("Enter :");
scanf("%s", str2);
int recsend = sendto(ret, str2, strlen(str2), 0, (struct sockaddr * ) & receiver, sizeof(receiver));
if (recsend == -1) {
printf("sendto fails");
exit(0);
}
if (strcmp(str2, "exit") == 0)
break;
}
close(ret);
return 0;
}
Sender
#include<stdio.h>
#include<stdlib.h>
#include<sys/socket.h>
#include<sys/types.h>
#include<netinet/in.h>
#include<netinet/ip.h>
#include<string.h>
#include<unistd.h>
int main() {
int ret = socket(AF_INET, SOCK_DGRAM, 0);
if (ret == -1) {
printf("\nsocket creation fails");
exit(0);
} else
printf("\nsocket creation succeeds");
struct sockaddr_in receiver;
int port;
printf("\nEnter port:");
scanf("%d", & port);
receiver.sin_family = AF_INET;
receiver.sin_port = htons(port);
receiver.sin_addr.s_addr = INADDR_ANY;
char str[15], str2[15];
int addrlen1 = sizeof(receiver);
struct sockaddr_in sender;
int addrlen = sizeof(sender);
while (1) {
printf("Enter:");
scanf("%s", str);
int send = sendto(ret, str, strlen(str), 0, (struct sockaddr * ) & receiver, addrlen1);
if (send == -1) {
printf("sendto fails");
exit(0);
}
if (strcmp(str, "exit") == 0)
break;
int senrec = recvfrom(ret, str2, sizeof(str2), 0, (struct sockaddr * ) & sender, & addrlen);
printf("\n");
printf("Received:");
str2[senrec] = '\0';
if (strcmp(str2, "exit") == 0)
break;
if (senrec == -1) {
printf("recvfrom fails\n");
exit(0);
}
printf("%s\n", str2);
}
close(ret);
return 0;
}
Connect both to different networks and get your server's ip address.
Change your client's receiver ip and port to:
receiver.sin_addr.s_addr = inet_addr("8.8.8.8"); // Ip address of your server.
receiver.sin_port=htons(port); // Whatever port your server is listening to
I am required to develop a stripped down version of online IDE. It will follow a client-server architecture. Client side will have three commands.
CREATE
RUN
QUIT
When the client chooses 'create' , the command would be sent to a server. The server will open windows. The first window will be a text editor in which the user will be able to write the code. The second window will act like an automatic parser which will parse the program that the users have written in the first window. The server side will read the user program at an interval of 1 second and parse the program using Lex and yacc. Any error found in the program should be reported in window 2. If there are no errors, the window will simply state "No error".
I have done till parsing part. But i could not understand, how to open a terminal from program and print error to that terminal.
I am posting my code here.
SERVER SIDE:
#include<stdio.h>
#include<stdlib.h>
#include<string.h> // This is for string related call.
#include<errno.h> // This is for error handling.
#include<limits.h> // this is for different type limit checking.
#include<ctype.h> // This is for different type checking.
#include<fcntl.h> // This is for unblocking socket.
#include<unistd.h> // this is for different type typical system call.
#include<sys/socket.h> // This header file defines miscellaneous socket related constant, types, and function.
#include<sys/types.h> // This header file defines miscellaneous types
#include<sys/sem.h> // This header file defines semaphores related types, function.
#include<sys/wait.h> // This header file defines blocking and wait related types and function.
#include<sys/ipc.h> // This header file defines mainly interprocess communication related structures.
#include<netinet/in.h> // This header file defines system parameter related to address.
#include<arpa/inet.h> // This header file defines different types macros .
#include<time.h> // This header file is included for getting times.
#include<signal.h>
#include<netdb.h>
#include<sys/shm.h> // This header file is included for shared memory .
#define PORT "5000" // This is the port server will be listening on
#define MAX 4096
#define NAZMUL
extern void parse(FILE*,FILE*);
int listener; // Server will be listening on this socket id.
/*.....................This function convert the IP address................................*/
void *convert(struct sockaddr *sa)
{
if(sa->sa_family == AF_INET)
return &(((struct sockaddr_in *)sa)->sin_addr);
return &(((struct sockaddr_in6 *)sa)->sin6_addr);
}
/*.........................................................................................*/
/*...............We are handling SIGINT SIGNAL here..........................................*/
void sigint_handler(int sig)
{
int nbytes;
char buffer[MAX];
strcpy(buffer, "quit");
#if hi
if((nbytes = send(new_fd, buffer, strlen(buffer) + 1, 0)) < 0)
{
if(nbytes == 0)
{
printf("SERVER: client is closed\n");
close(new_fd);
close(listener);
exit(EXIT_SUCCESS);
}
else
{
perror("SERVER:");
close(new_fd);
close(listener);
exit(EXIT_FAILURE);
}
}
close(listener);
close(new_fd);
#endif
exit(EXIT_SUCCESS);
}
/*............................................................................................*/
/*.......................We are handling SIGCHLD signal here..................................*/
void sigchild_handler(int sig)
{
// waitpid() might overwrite errno, so we save and restore it:
int saved_errno = errno;
while(waitpid(-1, NULL, WNOHANG) > 0);
errno = saved_errno;
}
/*..............................................................................................*/
/*...........................We are generating random number here...............................*/
int main()
{
int yes = 1; // this for setsockopt()
int status; // this is for holding return value of getaddrinfo()
int proces_id_gedit; // this will hold return value of fork()
int flags; // this for fcntl() call
char file_name[128]; // This is for saving filename.
char command[128],filenameout[128];
FILE *fp, *output_fp;
int create_flag = 0; // To check whether create command came or not
char *line = NULL;
size_t length = 0;
ssize_t nread;
struct sigaction for_sigint, for_sigchild; // these struct, we have to pass to sigaction()
char buffer[MAX]; // this will be used in send(), recv()
int nbytes; // This will hold return value of send(), recv()
int new_fd; // newly accept()ed socket descriptor.
struct sockaddr_storage client_addr; //it will hold client socket address.
char client_IP[INET6_ADDRSTRLEN]; // It will hold the ip address of client ip address.
socklen_t addr_len; // It will hold length of client ip address.
/*................GET us an successful socket and bind it...........................................*/
struct addrinfo hints, *ref, *p;
memset(&hints, 0, sizeof hints);
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = AI_PASSIVE;
if((status = getaddrinfo(NULL, PORT, &hints, &ref)) != 0)
{
fprintf(stderr, "SERVER: getaddrinfo:%s\n",gai_strerror(status) );
exit(EXIT_FAILURE);
}
for(p = ref; p != NULL; p = p->ai_next)
{
if((listener = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1)
{
continue;
}
if(setsockopt(listener, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1)
{
perror("SERVER:");
exit(EXIT_FAILURE);
}
/*....Setting the socket in non-blocking mode...*/
if ((flags = fcntl(listener, F_GETFL, 0)) < 0)
{
perror("SERVER(flags = fcntl):");
continue;
}
if (fcntl(listener, F_SETFL, flags | O_NONBLOCK) < 0)
{
perror("SERVER( fcntl):");
continue;
}
/*..............................................*/
if(bind(listener, p->ai_addr, p->ai_addrlen) == -1)
{
continue;
}
break; // we get successfull socket and bind, so we do not need to traverse anymore.
}
if(p == NULL) //checking whether we get a successful binding socket or not
{
fprintf(stderr, "we did not get successful binding socket\n");
exit(EXIT_FAILURE);
}
freeaddrinfo(ref);
/*..................we are handling here SIGINT SIGNAL....................................*/
for_sigint.sa_handler = sigint_handler;
for_sigint.sa_flags = 0;
sigemptyset(&for_sigint.sa_mask);
if(sigaction(SIGINT, &for_sigint, NULL) < 0)
{
perror("SERVER(sigint):");
exit(EXIT_FAILURE);
}
/*............................................................................................*/
/*.......................We are handling SIGCHLD signal here.................................*/
for_sigchild.sa_handler = sigchild_handler;
for_sigchild.sa_flags = SA_RESTART;
sigemptyset(&for_sigchild.sa_mask);
if(sigaction(SIGCHLD, &for_sigchild, NULL) < 0)
{
perror("SERVER(SIGCHLD):");
exit(EXIT_FAILURE);
}
/*.............................................................................................*/
listen(listener, 5); // we are listening here.
printf("SERVER:We are waiting for connection......................................\n");
for(;;)
{
addr_len = sizeof(client_addr);
if((new_fd = accept(listener, (struct sockaddr *)&client_addr, &addr_len)) < 0) // we are accepting new connection here.
{
}
else
{
/*....Setting the socket in non-blocking mode...*/
if ((flags = fcntl(new_fd, F_GETFL, 0)) < 0)
{
perror("SERVER(flags = fcntl):");
continue;
}
if (fcntl(new_fd, F_SETFL, flags | O_NONBLOCK) < 0)
{
perror("SERVER( fcntl):");
continue;
}
/*..............................................*/
inet_ntop(client_addr.ss_family, convert((struct sockaddr *)&client_addr), client_IP, sizeof client_IP);
printf("SERVER: We got connection from %s\n",client_IP );
if( fork() == 0)
{
close(listener); // child process does not need this.
for(;;)
{
memset(buffer, 0, 4096);
if((nbytes = recv(new_fd, buffer, MAX, 0)) == 0)
{
printf("SERVER: client is closed\n");
close(new_fd);
close(listener);
exit(EXIT_SUCCESS);
}
else
{
if(strcmp(buffer, "quit") == 0)
{
memset(buffer, 0, 4096);
strcpy(buffer, "quit");
if((nbytes = send(new_fd, buffer, strlen(buffer) + 1, 0)) < 0)
{
if(nbytes == 0)
{
printf("SERVER: client is closed\n");
close(new_fd);
close(listener);
exit(EXIT_SUCCESS);
}
else
{
}
}
else
{
if(create_flag == 1)
{
remove(file_name);
remove(filenameout);
create_flag = 0;
}
printf("SERVER: Connection with client %d is closed\n",new_fd );
close(new_fd);
close(listener);
exit(EXIT_SUCCESS);
}
}
else if(strcmp(buffer, "create") == 0)
{
printf("create command came\n");
memset(buffer, 0, 4096);
strcpy(buffer, "we got create command");
if((nbytes = send(new_fd, buffer, strlen(buffer) + 1, 0)) == 0)
{
printf("SERVER: client is closed\n");
close(new_fd);
close(listener);
exit(EXIT_SUCCESS);
}
sprintf(file_name, "%d.txt",getpid() );
sprintf(filenameout,"%dout.txt",getpid());
sprintf(command,"gedit %s",file_name);
signal(SIGCHLD, SIG_IGN);
if((proces_id_gedit= fork())== 0)
{close(new_fd);
system(command);
}
else
create_flag = 1;
}
else if(strcmp(buffer, "run") == 0)
{
printf("run command came\n");
memset(buffer, 0, 4096);
output_fp = fopen(filenameout, "r");
while((nread = getline(&line, &length, output_fp)) != -1)
{
strcat(buffer, line);
}
free(line);
fclose(output_fp);
//printf("%s\n",buffer );
if((nbytes = send(new_fd, buffer, strlen(buffer) + 1, 0)) == 0)
{
if(nbytes == 0)
{
printf("SERVER: client is closed\n");
close(new_fd);
close(listener);
exit(EXIT_SUCCESS);
}
else
{
}
}
char temp[128];
sprintf(temp, "kill -9 %d",proces_id_gedit);
//printf("%s\n",temp );
system(temp);
remove(filenameout);
remove(file_name);
create_flag = 0;
}
else
{
#if nazmul
memset(buffer, 0, 4096);
strcpy(buffer, "you entered invalid command");
if((nbytes = send(new_fd, buffer, strlen(buffer) + 1, 0)) < 0)
{
if(nbytes == 0)
{
printf("SERVER: client is closed\n");
close(new_fd);
close(listener);
exit(EXIT_SUCCESS);
}
else
{}
}
#endif
}
if(create_flag == 1)
{
sleep(1);
fp = fopen(file_name, "r");
output_fp=fopen(filenameout, "w");
if ( fp != NULL)
{
//printf("we are calling parse\n");
parse(fp, output_fp);
fclose(fp);
}
fclose(output_fp);
}
}
}/*..........................................END OF FOR LOOP OF EACH CLIENT HANDLING PROCESS................*/
}/*..............................................END OF FORK IF BLOCK...........................................*/
else
{
close(new_fd); // parent does not need this
continue;
}
}/*..................................................END OF ACCEPT ELSE BLOCK....................................*/
}/*......................................................END OF OF MAIN FOR LOOP.......................................*/
}/*..........................................................END OF MAIN BLOCK.........................................................*/
I am just posting server side here. This might be big code to go through. You can answer just without reading the code. I assumed that I run both client and server on my machine.
I have code for a server that can handle multiple clients. The client program can connect to the server and issue Unix commands such as ls, date, clear, etc. I have two problems that I cannot figure out. 1) When I initially type ls as an argument it will return some weird garbage, and then if I do ls again then it starts working properly. So only in the beginning, it will give me garbage. 2) When I type the argument 'ps -ael' into the terminal, it will work properly, but then after that I get a 'Failed' message, which is coming from the Client code, specifically at the while(1) loop where if (send(clientSocket, s, echolen, 0) != echolen), this is where the error is occurring. I was curious to know if someone could point to what the problem could be, I think it might be because I create a char array that's too big but I'm not sure.
Client:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#define PORT 4444
#define BUFFSIZE 2048
int main(int argc, char *argv[]){
int clientSocket, ret, portnum;
struct sockaddr_in serverAddr;
int received = 0;
unsigned int echolen;
char buffer[1024];
if(argc < 3){
fprintf(stderr,"usage %s <server-ip-addr> <server-port>\n", argv[0]);
exit(0);
}
portnum = atoi(argv[2]);
clientSocket = socket(AF_INET, SOCK_STREAM, 0);
if(clientSocket < 0){
printf("Error in connection.\n");
exit(1);
}
printf("Client Socket is created.\n");
memset(&serverAddr, '\0', sizeof(serverAddr));
// memset(&buffer, '\0', sizeof(buffer));
// serverAddr.sin_family = AF_INET;
// serverAddr.sin_port = htons(PORT);
// serverAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
// bzero((char *) &serverAddr, sizeof(serverAddr));
serverAddr.sin_family = AF_INET;
if(!inet_aton(argv[1], &serverAddr.sin_addr)){
fprintf(stderr, "Error invalid server IP address\n");
exit(1);
}
serverAddr.sin_port = htons(portnum);
ret = connect(clientSocket, (struct sockaddr*)&serverAddr, sizeof(serverAddr));
if(ret < 0){
printf("Error in connection.\n");
exit(1);
}
printf("Connected to server.\n");
char s[100];
while(1){
fgets(s, 100, stdin);
s[strlen(s)-1]='\0';
echolen = strlen(s);
/* send() from client; */
if (send(clientSocket, s, echolen, 0) != echolen)
{
printf("Failed");
}
if(strcmp(s,"exit") == 0) // check if exit is typed
exit(0);
fprintf(stdout, "Message from server: ");
while (received < echolen)
{
int bytes = 0;
/* recv() from server; */
if ((bytes = recv(clientSocket, buffer, echolen, 0)) < 1)
{
printf("Failed to get Information");
}
received += bytes;
buffer[bytes] = '\0';
fprintf(stdout, buffer);
}
int bytes = 0;
do {
buffer[bytes] = '\0';
printf("%s\n", buffer);
} while((bytes = recv(clientSocket, buffer, BUFFSIZE-1, 0))>=BUFFSIZE-1);
buffer[bytes] = '\0';
printf("%s\n", buffer);
printf("\n");
}
}
Server:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#define PORT 4444
#define BUFFSIZE 2048
#define MAX 2048
void setup(char inputBuffer[], char *args[], int *background){
const char s[4] = " \t\n";
char *token;
token = strtok(inputBuffer, s);
int i = 0;
while(token != NULL){
args[i] = token;
i++;
token = strtok(NULL, s);
}
args[i] = NULL;
}
void HandleClient(int sock){
char buffer[BUFFSIZE];
int received = -1;
char data[MAX];
memset(data, 0, MAX);
while(1){
data[0] = '\0';
if((received = recv(sock, buffer, BUFFSIZE, 0)) < 0){
printf("Error");
}
buffer[received] = '\0';
strcat(data, buffer);
if(strcmp(data, "exit") == 0){
exit(0);
}
puts(data);
char *args[100];
setup(data, args, 0);
int pipefd[2], length;
if(pipe(pipefd)){
printf("failed to create pipe");
}
pid_t pid = fork();
char path[MAX];
if(pid==0)
{
close(pipefd[0]); // close the readonly side of the pipe
//close(1); // close the original stdout
dup2(pipefd[1],1); // duplicate pipfd[1] to stdout
dup2(pipefd[1], fileno(stderr));
//close(pipefd[0]); // close the readonly side of the pipe
close(pipefd[1]); // close the original write side of the pipe
printf("before execvp");
execvp(args[0],args); // finally execute the command
// exit(0);
}
else
if(pid>0)
{
close(pipefd[1]);
memset(path,'\0',MAX);
while(length=read(pipefd[0],path,MAX-1)){
//printf("Data read so far %s\n", path);
if(send(sock,path,strlen(path),0) != strlen(path) ){
printf("Failed");
}
fflush(NULL);
//printf("Data sent so far %s\n", path);
memset(path,0,MAX);
}
close(pipefd[0]);
//exit(1); removed so server will not terminate
}
else
{
printf("Error !\n");
exit(0);//
}
}
}
int main(){
int sockfd, ret;
struct sockaddr_in serverAddr;
int newSocket;
struct sockaddr_in newAddr;
socklen_t addr_size;
char buffer[1024];
pid_t childpid;
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if(sockfd < 0){
printf("Error in connection.\n");
exit(1);
}
printf("Server Socket is created.\n");
memset(&serverAddr, '\0', sizeof(serverAddr));
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons(PORT);
serverAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
ret = bind(sockfd, (struct sockaddr*)&serverAddr, sizeof(serverAddr));
if(ret < 0){
printf("Error in binding");
exit(1);
}
printf("Bind to port %d\n", 4444);
if(listen(sockfd, 10) == 0){
printf("Listening....\n");
}else{
printf("Error in binding.\n");
}
while(1){
newSocket = accept(sockfd, (struct sockaddr*) &newAddr, &addr_size);
if(newSocket < 0){
exit(1);
}
printf("Connection accepted from %s:%d\n", inet_ntoa(newAddr.sin_addr), ntohs(newAddr.sin_port));
//worker
if((childpid = fork()) == 0){
close(sockfd);
while(1){
recv(newSocket, buffer, 1024, 0);
if(strcmp(buffer, ":exit") == 0){
printf("Disconnected from %s:%d\n", inet_ntoa(newAddr.sin_addr), ntohs(newAddr.sin_port));
break;
}else{
printf("Client: %s\n", buffer);
send(newSocket, buffer, strlen(buffer), 0);
bzero(buffer, sizeof(buffer));
}
HandleClient(newSocket);
}
}
}
close(newSocket);
return 0;
}
i have an infinite loop problem while im trying to send some messages from client to the server. Client has some commands like login, getusers, alias etc. and i want to check them into server. Here its my code.
CLIENT
#include<stdio.h>
#include<sys/socket.h>
#include<arpa/inet.h> // for inet_addr
#include <string.h>
#include <zconf.h>
int main(int argc, char *argv[]) {
int sock;
struct sockaddr_in server;
char message[2000], server_reply[2000];
//Create socket
sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock == -1) {
printf("Could not create socket");
}
server.sin_addr.s_addr = inet_addr("127.0.0.1");
server.sin_family = AF_INET;
server.sin_port = htons(8888);
//Connect to remote server
if (connect(sock, (struct sockaddr *) &server, sizeof(server)) < 0) {
perror("Connect failed. Error");
return 1;
}
puts("Connected to server\n");
//keep communicating with server
while (1) {
printf("> ");
scanf("%[^\n]s", message);
fflush(stdin);
//Send some data
if (send(sock, message, strlen(message), 0) < 0) {
puts("Send failed");
return 1;
}
//Receive a reply from the server
if (recv(sock, server_reply, 2000, 0) < 0) {
puts("recv failed");
break;
}
printf("Server's reply : %s ", server_reply);
}
close(sock);
return 0;
}
SERVER
#include<stdio.h>
#include<string.h> // for strlen
#include<stdlib.h>
#include<sys/socket.h>
#include<arpa/inet.h> // for inet_addr
#include<unistd.h> // for write
#include<pthread.h> // for threading, link with lpthread
#include "server.h"
#include "split.h"
#define MAX_CLIENT_NUMBER 100
void *connection_handler(void *);
struct User {
char userName[10];
int clientSocketNo;
};
struct User users[MAX_CLIENT_NUMBER];
void getUsers() {
printf("Number %d",userArrayIndex);
for (int i = 0; i < userArrayIndex; ++i) {
printf("%s\n", users[i].userName);
}
}
void addUserToArray(char userName[10], int socketNumber) {
printf("Client logged in as %s\n", userName);
strcpy(users[userArrayIndex].userName, userName);
users[userArrayIndex].clientSocketNo = socketNumber;
userArrayIndex++;
}
void loginUser(char userName[10], int socketNumber) {
char *message = "login successful";
write(socketNumber, message, strlen(message));
addUserToArray(userName, socketNumber);
}
void *connection_handler(void *socket_desc) {
//Get the socket descriptor
char receivedMessage[2000]; //client's message
int readControl;
int sock = *((int *) socket_desc);
while ((readControl = recv(sock, receivedMessage, 2000, 0)) > 0) {
char **parsedCommand = malloc(100); //parsedClientMessage
parsing(parsedCommand, receivedMessage, " ");
printf("MESSAGE %s\n",parsedCommand[0]);
if (strcmp(parsedCommand[0], "login") == 0) {
loginUser(parsedCommand[1], sock);
}
if (strcmp(parsedCommand[0], "getusers") == 0) {
getUsers();
}
if (strcmp(parsedCommand[0], "exit") == 0) {
close(sock);
return 0;
}
}
if (readControl == 0) {
puts("Client disconnected");
clientNumber--;
fflush(stdout);
} else if (readControl == -1) {
perror("recv failed");
}
//Free the socket pointer
free(socket_desc);
return 0;
}
int main(int argc, char *argv[]) {
int socket_desc, new_socket, c, *new_sock;
struct sockaddr_in server, client;
//Create Socket
socket_desc = socket(AF_INET, SOCK_STREAM, 0);
if (socket_desc == -1) {
puts("Could not create socket");
return 1;
}
server.sin_family = AF_INET;
server.sin_addr.s_addr = INADDR_ANY;
server.sin_port = htons(8888);
if (bind(socket_desc, (struct sockaddr *) &server, sizeof(server)) < 0) {
puts("Binding failed");
return 1;
}
listen(socket_desc, 3);
puts("Server started");
c = sizeof(struct sockaddr_in);
while ((new_socket = accept(socket_desc, (struct sockaddr *) &client, (socklen_t *) &c)) &&
clientNumber < MAX_CLIENT_NUMBER) {
pthread_t sniffer_thread/*[MAX_CLIENT_NUMBER]*/;
new_sock = malloc(1);
*new_sock = new_socket;
if (pthread_create(&sniffer_thread/*[clientNumber]*/, NULL, connection_handler,
(void *) new_sock) < 0) {
perror("Could not create thread");
return 1;
} else {
clientNumber++;
}
puts("Client connected");
}
if (new_socket < 0) {
perror("accept failed");
return 1;
}
return 0;
}
Its not full of my code but i think our problem in these parts. I dont understand why it happens. When i insert a break command into connection_handler's while loop, i cant send commands to the server anymore. Thanks...
I solved it. when i malloc the messages or replies, i give +1 to strlen(messsage).
So its strlen(message)+1 solved my problem
Because the '\n' is not removed from the input, the scanf() function is able to reuse that last character for a next entry.
The easiest solution to solve that problem is to clear the input
buffer fflush(stdin);.
while (1) {
printf("> ");
scanf("%[^\n]s", message);
fflush(stdin); // to clear \n from the buffer
//Send some data
if (send(sock, message, strlen(message), 0) < 0) {