Reputation: 1
/* 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.
Upvotes: 0
Views: 82
Reputation: 73161
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)
Upvotes: 1