I have a simple client-server program implemented in C where a client can send integers to a server and the server replies with their sums. However, there is a troubling Segmentation fault (core dumped) shown on the server side whenever the client disconnects suddenly. The Client:
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#define PORT 5010
int main(int argc, char **argv) {
char buf[BUFSIZ], buf2[BUFSIZ], message[BUFSIZ], serverReply[BUFSIZ];
int SOCKET;
struct sockaddr_in server;
SOCKET = socket(AF_INET, SOCK_STREAM, 0);
if (SOCKET < 0) {
perror("Could not create socket");
return -1;
}
printf("Socket created\n");
server.sin_addr.s_addr = inet_addr("127.0.0.1");
server.sin_family = AF_INET;
server.sin_port = htons(PORT);
if (connect(SOCKET, (struct sockaddr *) &server, sizeof(struct sockaddr_in)) < 0) {
perror("Could not connect");
return -1;
}
memset(&serverReply, 0, sizeof(serverReply));
printf("Connected to server.\nEnter first number: ");
scanf("%s", buf);
fflush(stdin);
printf("Enter second number: ");
scanf("%s", buf2);
strcat(buf, " ");
strcat(buf, buf2);
strcpy(message, buf);
if (send(SOCKET, message, strlen(message), 0) < 0) {
perror("Failed to send message");
return -1;
}
if (recv(SOCKET, serverReply, sizeof(serverReply), 0) < 0) {
perror("Could not receive message");
return -1;
}
printf("Server: %s", serverReply);
close(SOCKET);
}
The Server:
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <errno.h>
#define PORT 5010
int main(int argc, char *argv[]) {
char msg[BUFSIZ], reply[BUFSIZ];
struct sockaddr_in server, client;
int SOCKET, ACCEPT, READ, sockSize, num1, num2, option = 1, maxClients = 30,
h, clientSocket[maxClients], maxsd, sd, SELECT;
fd_set readfds;
for (h = 0; h < maxClients; h++) {
clientSocket[h] = 0;
}
SOCKET = socket(AF_INET, SOCK_STREAM, 0);
if (SOCKET == -1) {
perror("Could not create socket");
return -1;
}
if (setsockopt(SOCKET, SOL_SOCKET, SO_REUSEADDR, &option, sizeof(option)) == -1) {
perror("Could not set OPTNAME");
return -1;
}
server.sin_family = AF_INET;
server.sin_addr.s_addr = INADDR_ANY;
server.sin_port = htons(PORT);
printf("Created socket.\n");
if (bind(SOCKET, (struct sockaddr *) &server, sizeof(server)) < 0) {
perror("Could not bind");
return -1;
}
if (listen(SOCKET, 1) < 0) {
perror("Listen failed");
return -1;
}
printf("Server is listening.\n");
sockSize = sizeof(struct sockaddr_in);
while (1) {
FD_ZERO(&readfds);
FD_SET(SOCKET, &readfds);
maxsd = SOCKET;
for (h = 0; h < maxClients; h++) {
sd = clientSocket[h];
if (sd > 0) { FD_SET(sd, &readfds); }
if (sd > maxsd) { maxsd = sd; }
}
SELECT = select(maxsd + 1, &readfds, NULL, NULL, NULL);
if ((SELECT < 0) && (errno != EINTR)) {
perror("select error");
}
if (FD_ISSET(SOCKET, &readfds)) {
ACCEPT = accept(SOCKET, (struct sockaddr *) &server, (socklen_t *) &sockSize);
if (ACCEPT < 0) {
perror("Could not accept client");
return -1;
}
for (h = 0; h < maxClients; h++) {
if (clientSocket[h] == 0) {
clientSocket[h] = ACCEPT;
break;
}
}
printf("Client has joined the server.\n");
}
for (h = 0; h < maxClients; h++) {
sd = clientSocket[h];
if (FD_ISSET(sd, &readfds)) {
READ = read(sd, msg, sizeof(msg));
if (READ == -1) {
perror("Could not receive message");
return -1;
}
if (READ == 0) {
printf("Client disconnected\n");
fflush(stdout);
clientSocket[h]=0;
}
int e = 0;
char *p = strtok(msg, " ");
char *arr[2];
while (p != NULL) {
arr[e++] = p;
p = strtok(NULL, " ");
}
num1 = atoi(arr[0]);
num2 = atoi(arr[1]);
if ((strcmp(arr[0], "0") != 0 && num1 != 0) && (strcmp(arr[1], "0") != 0 && num2 != 0)) {
printf("Client: %d, %d\n", num1, num2);
sprintf(reply, "%d\n", num1 + num2);
if (write(sd, reply, strlen(reply)) < 0) {
perror("Could not send message");
return -1;
}
memset(&reply, 0, sizeof(reply));
} else {
printf("Conversion error");
strcpy(reply, "Conversion error.");
if (write(sd, reply, strlen(reply)) < 0) {
perror("Could not send message");
return -1;
}
}
}
}
}
}
How can the segfault be solved? How else can the codes be improved?
The segfault comes from the atoi function since NULL is received. Checking for NULL seems to do the trick...
Related
I am implementing stop&wait with c and udp socket programming. with one client it works but with more than one client it dosen't work.
server.c
struct sockaddr_in newAddr;
socklen_t addr_size = sizeof(newAddr);
fd_set rset;
int frame_id = 0;
Frame frame_recv;
Frame frame_send;
int socket_desc = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (socket_desc < 0) {
perror("Socket Creation Failed ");
exit(EXIT_FAILURE);
}
else {
perror("Socket Created ");
}
if (bind(socket_desc, (struct sockaddr *) &server_addr,
sizeof(server_addr)) < 0 ) {
perror("Bind Failed ");
exit(EXIT_FAILURE);
}
else {
perror("Bind Done ");
}
printf("Listening for Messages...\n");
FD_ZERO(&rset);
while (1) {
FD_SET(socket_desc, &rset);
select(socket_desc + 1, &rset, NULL, NULL, NULL);
if (FD_ISSET(socket_desc, &rset)) {
int recv_size = recvfrom(socket_desc, &frame_recv, sizeof(Frame), 0,
(struct sockaddr *) &newAddr, &addr_size);
if (recv_size > 0 && frame_recv.frame_kind == 1 &&
frame_recv.sq_no == frame_id) {
printf("[+]Frame Received: %s\n", frame_recv.packet.data);
frame_send.sq_no = 0;
frame_send.frame_kind = 0;
frame_send.ack = frame_recv.sq_no + 1;
sendto(socket_desc, &frame_send, sizeof(frame_send), 0,
(struct sockaddr*)&newAddr, addr_size);
printf("[+]Ack Send\n");
}
else {
printf("[+]Frame Not Received\n");
break;
}
frame_id ++;
}
}
close(socket_desc);
client.c
char buffer[1024];
socklen_t addr_size;
int frame_id = 0;
Frame frame_send;
Frame frame_recv;
int ack_recv = 1;
int socket_desc = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (socket_desc < 0) {
perror("Socket Creation Failed ");
exit(EXIT_FAILURE);
}
else {
perror("Socket Created ");
}
while (1) {
if (ack_recv == 1) {
frame_send.sq_no = frame_id;
frame_send.frame_kind = 1;
frame_send.ack = 0;
printf("Enter Data: ");
scanf("%s", buffer);
strcpy(frame_send.packet.data, buffer);
sendto(socket_desc, &frame_send, sizeof(Frame), 0,
(struct sockaddr*)&server_addr, sizeof(server_addr));
printf("[+]Frame Send\n");
}
int addr_size = sizeof(server_addr);
int recv_size = recvfrom(socket_desc, &frame_recv, sizeof(frame_recv), 0 ,(struct sockaddr*)&server_addr, &addr_size);
if (recv_size > 0 && frame_recv.sq_no == 0 && frame_recv.ack == frame_id + 1) {
printf("[+]Ack Received\n");
ack_recv = 1;
}
else {
printf("[-]Ack Not Received\n");
ack_recv = 0;
break;
}
frame_id++;
}
close(socket_desc);
header.h
typedef struct packet {
char data[1024];
} Packet;
typedef struct frame {
int frame_kind; //ACK:0, SEQ:1 FIN:2
int sq_no;
int ack;
Packet packet;
} Frame;
I found that frame_recv.sq_no and frame_id have different value when the second client run.
I read questions with same topic, but could not find out the error from my code.
I have 2 programs, a client and a server, the client can send data to the server, and I want to send all the new data received on the server from one client to the other connected clients with a thread, each connected client has a child process in the server that receives the data, here is an illustration of what I want to do.
server.c :
int main(int argc, char const *argv[]) {
Liste *ListeTache;
int sh_id;
int i,j;
size_t sizeMatrix = sizeof_dm(30,100,sizeof(char));
ListeTache=malloc(sizeof(Liste));
init_Liste(ListeTache);
key_t keyfile = ftok("keyFileIpc.txt",10);
if((sh_id = shmget(keyfile,sizeof(Liste),IPC_CREAT|0666)) == -1) {
perror("shmget");
exit(1);
}
if ((ListeTache = shmat(sh_id, NULL, 0)) == (void *) -1) {
perror("shmat");
exit(1);
}
init_Liste(ListeTache);
printSharedMem(ListeTache->s);
//creation de la socket pour le TCP
int sock = socket(AF_INET, SOCK_STREAM, 0);
if(sock == -1) {
perror("socket error\n");
exit(errno);
}
struct sockaddr_in sin = { 0 };
sin.sin_addr.s_addr = htonl(INADDR_ANY);
sin.sin_family = PF_INET;
sin.sin_port = htons(31470);
if(bind (sock, (struct sockaddr *) &sin, sizeof sin) == -1) {
perror("bind()");
exit(errno);
}
if(listen(sock, 3) == -1) {
perror("listen error\n");
exit(errno);
}
struct sockaddr_in csin = { 0 };
int idSock;
socklen_t lg = sizeof(struct sockaddr_in);
char msg[100];
do {
if ((idSock = accept(sock, (struct sockaddr *) &csin, &lg)) == -1) {
perror("accept error\n");
exit(errno);
}
if (!fork()) {
close(sock);
printSharedMem(ListeTache->s);
printf("i'm here\n");
// we send here the initial data
if(send(idSock, ListeTache, sizeof(Liste), 0) < 0) {
perror("send()");
exit(errno);
}
pthread_t idThread;
do {
if(recv(idSock, ¶msReq, sizeof(paramsReq), 0) < 0) {
perror("paramsReq :recv error\n");
exit(errno);
}
//if recv something from a client then i want to send the change to all the others here
}
else
{
close(idSock);
}
} while (1);
free(ListeTache);
ListeTache=NULL;
shmctl(sh_id, IPC_RMID, NULL);
return 0;
}
client.c
void *listenServ (void *arg) {
paramsListenServ params = *((paramsListenServ *) arg);
paramsRequest paramsReq;
do {
if(recv(params.sockId, ¶msReq, sizeof(paramsReq), 0) < 0) {
perror("recv error\n");
exit(errno);
}
printf("%s \n", paramsReq.requestType);
if (!strcmp(paramsReq.requestType, "addRequest")) {
strcpy(¶ms.s[paramsReq.taskToModify*100], paramsReq.taskText);
printSharedMemo(params.s);
}
else if (!strcmp(paramsReq.requestType, "swapRequest")) {
char firstTask[100];
strcpy(firstTask, ¶ms.s[paramsReq.tasksToSwap.firstTask*100]);
strcpy(¶ms.s[paramsReq.tasksToSwap.firstTask*100], ¶ms.s[paramsReq.tasksToSwap.secondTask*100]);
strcpy(¶ms.s[paramsReq.tasksToSwap.secondTask*100], firstTask);
printSharedMemo(params.s);
}
else if (!strcmp(paramsReq.requestType, "modifyRequest")) {
strcpy(¶ms.s[paramsReq.taskToModify*100], paramsReq.taskText);
printSharedMemo(params.s);
}
else if (!strcmp(paramsReq.requestType, "deleteRequest")) {
int i = paramsReq.taskToModify;
while (i < 29 && strlen(¶ms.s[i * 100]) != 0) {
strcpy(¶ms.s[i*100], ¶ms.s[(i + 1)*100]);
i++;
}
strcpy(¶ms.s[(paramsReq.head - 1)*100], "");
printSharedMemo(params.s);
}
/*printf("Message reçu du serveur : %s\n", msg);
memset(msg,0, sizeof msg);*/
} while (1);
pthread_exit(NULL);
}
int main(int argc, char const *argv[]) {
//creation d'un socket ppour le TCP
int sock = socket(AF_INET, SOCK_STREAM, 0);
Liste *ListeTache;
ListeTache=malloc(sizeof(Liste));
init_Liste(ListeTache);
int j;
if(sock == -1) {
perror("socket()");
exit(errno);
}
//initialisation de la structure de donné
struct sockaddr_in sin = { 0 };
sin.sin_family = PF_INET;
sin.sin_addr.s_addr = inet_addr("127.0.0.1");
sin.sin_port = htons((short)31470);
//connect to the server
if(connect(sock,(struct sockaddr *) & sin, sizeof(struct sockaddr_in)) == -1) {
perror("connect()");
exit(errno);
}
// we receive the initial data
if(recv(sock,ListeTache,sizeof(Liste), 0) < 0) {
perror("main :recv error\n");
exit(errno);
}
printSharedMemo(ListeTache->s);
pthread_t idThread;
paramsListenServ params;
params.s=ListeTache->s;
params.sockId = sock;
// this thread listen to the send that is in the server
if(pthread_create(&idThread, NULL, listenServ, ¶ms) != 0)
perror("pthread_create");
do {
//do changes
//we send the new data to the server
if(send(sock, ¶msReq, sizeof(paramsReq), 0) < 0) {
perror("send()");
exit(errno);
}
}
}
} while(1<=choice && choice<=4);
close(sock);
printf("La connexion avec le serveur a bien été fermée ! \n");
return 0;
}
My question is, if I use a thread and put it in a fork, how can the thread get the data sent from one client because the socket change from one client to another?
I can't seem to print what I enter in my client. I have compiled both without any error. Can't figure out why it isn't printing the desired output.
Q. What is wrong with my code ? How can I print a string with whitespaces through the client in the server.
Here is the code for the server.
/* Server Side program */
int sid,nid;
struct sockaddr_in q;
char x[100];
int len=sizeof(struct sockaddr_in);
sid=socket(PF_INET,SOCK_STREAM,IPPROTO_TCP);
q.sin_family=PF_INET;
q.sin_port=1600;
q.sin_addr.s_addr=0;
bind(sid,&q,len);
listen(sid,20);
while(1)
{
memset(x,0,sizeof(x));
nid=accept(sid,&q,&len);
read(nid,x,100);
printf("%s\n",x);
}
Here is the code for the client.
/*client side program*/
int sid,status;
struct sockaddr_in q;
int len=sizeof(struct sockaddr_in);
char x[100];
sid=socket(PF_INET,SOCK_STREAM,IPPROTO_TCP);
q.sin_family=PF_INET;
q.sin_port=1600;
q.sin_addr.s_addr=0;
status=connect(sid,&q,len);
if(status==-1)
{
printf("Connection failure");
exit(0);
}
while(1)
{
printf("Enter string to send : ");
scanf("%[^\n]s",x);
write(sid,x,strlen(x));
if(strcmp(x,"bye")==0)
break;
}
There is all kinds of problems with your code. Lack of error handling. Incorrect use of printf() and scanf(). Resource leaks.
Try something more like this instead:
Server:
int main()
{
int sid, nid;
struct sockaddr_in q;
char x[100];
socklen_t qlen;
ssize_t xlen;
sid = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (sid < 0)
{
perror("socket failure");
return -1;
}
q.sin_family = AF_INET;
q.sin_port = htons(1600);
q.sin_addr.s_addr = INADDR_ANY;
if (bind(sid, &q, sizeof(q)) < 0)
{
perror("bind failure");
return -1;
}
if (listen(sid, 20) < 0)
{
perror("listen failure");
return -1;
}
while(1)
{
qlen = sizeof(q);
nid = accept(sid, &q, &qlen);
if (nid < 0)
{
perror("accept failure");
return -1;
}
while ((xlen = read(nid, x, sizeof(x))) > 0)
{
printf("Received: '%.*s'\n", xlen, x);
}
if (xlen < 0)
perror("read failure");
else
printf("client disconnected\n");
close(nid);
}
return 0;
}
Client:
int main()
{
int sid, xlen;
struct sockaddr_in q;
char x[100];
sid = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (sid < 0)
{
perror("socket failure");
return -1;
}
q.sin_family = AF_INET;
q.sin_port = htons(1600);
q.sin_addr.s_addr = inet_addr("server ip here"); // or INADDR_LOOPBACK (127.0.0.1)
if (connect(sid, &q, sizeof(q)) < 0)
{
printf("connect failure");
return -1;
}
while(1)
{
printf("Enter string to send : ");
if (!fgets(x, sizeof(x), stdin))
break;
xlen = strlen(x);
if ((xlen > 0) && (x[xlen-1] == '\n'))
{
x[xlen-1] = '\0';
--xlen;
}
if (write(sid, x, xlen) < 0)
{
perror("write failure");
break;
}
if (strcmp(x, "bye") == 0)
break;
}
close(sid);
return 0;
}
Im trying to create connection between 2 clients via a server. In this program, client sends a message to the server and server post it to the target client. But there is a little problem between this operation. Transmitter one cannot send another message before it receive some message or receiver one cannot see the received message before send a message. Video should explain better.
You can find scanf function in below of client.c codes
CLIENT
//
// Created by berkin on 18.12.2016.
//
#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]%*c", message);
fflush(stdin);
//Send some data
if (send(sock, message, strlen(message)+1, 0) < 0) {
puts("Send failed");
return 1;
}
if (recv(sock, server_reply, 2000, 0) < 0) {
puts("recv failed");
break;
}
//Receive a reply from the server
printf ("\033[32;1m %s \033[0m\n",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 "split.h"
#define MAX_CLIENT_NUMBER 100
void *connection_handler(void *);
struct User {
char userName[10];
int clientSocketNo;
};
unsigned int clientNumber = 0;
unsigned int userArrayIndex = 0;
struct User users[MAX_CLIENT_NUMBER];
//FOR GETUSERS COMMAND
void getUsers(int socketNumber) {
char *userString = malloc(100);
if (users[0].userName != NULL) {
strcpy(userString, users[0].userName);
strcat(userString, ",");
} else {
return;
}
for (int i = 1; i < userArrayIndex; ++i) {
strcat(userString, users[i].userName);
strcat(userString, ",");
}
write(socketNumber, userString, strlen(userString) + 1);
}
//AFTER LOGIN COMMAND, ADD TO THE ARRAY
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++;
}
//LOGIN COMMAND
void loginUser(char userName[10], int socketNumber) {
char *message = "login successful";
write(socketNumber, message, strlen(message) + 1);
addUserToArray(userName, socketNumber);
}
//SEND MESSAGE IF USER FOUND
void sendMessage(struct User user, char *message){
write(user.clientSocketNo,message,strlen(message) + 1);
}
//SEARCH USER FROM ARRAY
struct User searchUser(char searchName[10]){
for (int i = 0; i < userArrayIndex; ++i) {
if(strcmp(users[i].userName,searchName) == 0){
return users[i];
}
}
}
void *connection_handler(void *socket_desc) {
//Get the socket descriptor
char receivedMessage[2000]; //client's message
int readControl;
int parsedItemNumber = 0;
int sock = *((int *) socket_desc);
while ((readControl = recv(sock, receivedMessage, 2000, 0)) > 0) {
char *parsedCommand[50]; //parsedClientMessage
parsedItemNumber = parsing(parsedCommand, receivedMessage, " ");
if (strcmp(parsedCommand[0], "login") == 0) {
loginUser(parsedCommand[1], sock);
}
else if (strcmp(parsedCommand[0], "getusers") == 0) {
getUsers(sock);
}
else if (strcmp(parsedCommand[0], "exit") == 0) {
close(sock);
return 0;
}
else{
if(parsedCommand[0] != NULL){
struct User find = searchUser(parsedCommand[0]);
if(find.userName != NULL){
char *message = malloc(2000);
if(parsedCommand[1] != NULL){
strcpy(message,parsedCommand[1]);
strcat(message," ");
}
for (int i = 2; i < parsedItemNumber; ++i) {
strcat(message,parsedCommand[i]);
strcat(message," ");
}
sendMessage(find,message);
}
else{
perror("Your input was wrong");
}
}
}
}
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;
}
i don't know why the select function don't return any result.
I put the server in execution with this command:
./server 5555
and i try to send any character from another terminal, using:
nc 127.0.0.1 5555
and
any string to send
This is the source code of the server.c
#include <stdlib.h>
#include <stdio.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <errno.h>
#define MAXSIZE 1000
int main(int argc, char **argv) {
int socketfd, connectedfd, maxfd;
int ris, i, len, ris1, sent, opt;
struct sockaddr_in serverS, clientS;
short int localServerPort;
fd_set rdfs, wrfs;
char buffer[MAXSIZE];
if (argc != 2) {
printf("necessario un parametro PORTNUMBER");
exit(1);
} else {
localServerPort = atoi(argv[1]);
}
socketfd = socket(AF_INET, SOCK_STREAM, 0);
if (socketfd < 0) {
printf("socket() error\n");
exit(1);
}
opt = 1;
ris = setsockopt(socketfd, SOL_SOCKET, SO_REUSEADDR, (char *)&opt, sizeof(opt));
if (ris < 0) {
printf ("setsockopt() SO_REUSEADDR failed, Err: %d \"%s\"\n", errno,strerror(errno));
exit(1);
}
memset(&serverS, 0, sizeof(serverS));
serverS.sin_family = AF_INET;
serverS.sin_addr.s_addr = htonl(INADDR_ANY);
serverS.sin_port = htons(localServerPort);
ris = bind(socketfd, (struct sockaddr*)&serverS, sizeof(serverS));
if (ris < 0) {
printf("bind() error");
exit(1);
}
ris = listen(socketfd, 10);
if (ris < 0) {
printf("listen() error");
exit(1);
}
len = sizeof(clientS);
connectedfd = accept(socketfd, (struct sockaddr*)&clientS, &len);
if (connectedfd < 0) {
printf("accept() error");
exit(1);
} else {
printf("Connesso con: %s:%d - descrittore: %d\n", inet_ntoa(clientS.sin_addr), ntohs(clientS.sin_port), connectedfd);
}
fd_set tempset;
FD_ZERO(&rdfs);
//FD_ZERO(&wrfs);
FD_SET(connectedfd, &rdfs);
maxfd = connectedfd + 1;
while (1) {
printf("Select...\n");
ris = select(connectedfd, &rdfs, NULL, NULL, NULL);
printf("test\n");
if (ris == 0) {
printf("select() timeout error\n");
} else if (ris < 0 && errno != EINTR) {
printf("select() error\n");
} else if (ris > 0) {
printf("test ris > 0\n");
for (i = 0; i < maxfd+1; i++) {
if (FD_ISSET(i, &rdfs)) {
do {
ris = recv(i, buffer, MAXSIZE, 0);
} while (ris == -1 && errno == EINTR);
if (ris > 0) {
buffer[ris] = 0;
printf("Echoing: %s\n", buffer);
sent = 0;
do {
ris1 = send(i, buffer+sent, ris-sent, MSG_NOSIGNAL);
if (ris1 > 0)
sent += ris1;
else if (ris1 < 0 && errno != EINTR);
break;
} while (ris > sent);
}
else if (ris == 0) {
close(i);
FD_CLR(i, &rdfs);
}
else {
printf("Error in recv(): %s\n", strerror(errno));
}
}
}
}
}
return(0);
}
Why the execution remain locked at "Select...\n"?
Thanks to all!
From http://linux.die.net/man/2/select, the first param passed should be the highest-numbered file descriptor in any of the three sets (read/write/exception), plus 1. I would try the following:
ris = select(connectedfd+1, &rdfs, NULL, NULL, NULL);