socket programming problem mit select()

scriptkiddiie

Grünschnabel
hey leute

ich habe unter linux einen einfach chat in C geschrieben mit 2 client programmen die identisch sind.

und der chat läuft auch ... nur hab ich ein problem mit meinem select()

ziel ist es, dass beide clients gleichzeitig unabhängig vom andern nachrichten senden und empfangen können.

ich kann auch nachrichten schicken und empfangen. nur hab ich das problem, dass ich beim einlesen des zu sendenden strings mit fgets(buffer, BUF_SIZE, stdin) eine blocking funktion habe und so erst die erhaltene nachricht des andern clients lesen kann wenn ich was eingelesen habe. d.h es soll möglich sein die nachricht zu lesen während ich am einlesen bin.

geht das überhaupt. weil fgets() ist ja blockierend. geht das vieleicht mit einem timestopper der wenn nach einer gewissen zeit nichts geschrieben wurde recvfrom() ausführt?
kann man vieleicht was mit stdin machen ?
wie schon gesagt sind beide clients identisch, das protokoll ist udp und habs auf dem gleichen rechner getestet also ./client1 127.0.0.1 1235 und ./client2 127.0.0.1 1234

wäre froh über alle hilfen

thx
der quelltext ist im anhang
 

Anhänge

Zuletzt bearbeitet:
ich konnte das problem vom empfangen während dem eintippen beheben.

Jetzt kann ich aber nur noch im code eingegebene strings zum testen schicken.

kann mir jemand vieleicht sagen wie ich das eingelesen (stdin) in meinen buffer reinkriege ohne fgets
 

Anhänge

Zuletzt bearbeitet:
Kannst du den Programmcode nicht noch mal jetzt wo er funktioniert "richtig" hier reinstellen (nicht nur im Anhang, denn da kommen in der TXT Datei nur komische Symbole).
Wär ja schön für andere, mal ein funktionierendes Bsp. zu sehen!
Ich hätte auf jeden Fall Interesse!
 
ja klar kann ich machen :D

wie gesagt, sind einfach zwei clients mit UDP die Strings schicken können.
habs auf dem eignen rechner getestet.

./chat_client1 127.0.0.1 1235 1234
./chat_client2 127.0.0.1 1234 1235



#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <netinet/in.h>
#include <unistd.h>

#define BUF_SIZE 4096

int main(int argc, char *argv[])
{

int s, MY_PORT, PORT, size_myaddr;
int max, bytes;
char buffer[BUF_SIZE];
struct sockaddr_in my_addr;
struct sockaddr_in client_addr;
fd_set rfds;

//check the arguments
if(argc != 4)
{
fprintf(stderr, "usage: missing <host>, <port> <myport>\n", argv[0]);
return 1;
}
PORT = atoi(argv[2]);
MY_PORT = atoi(argv[3]);
//create socket
s = socket(AF_INET, SOCK_DGRAM, 0);
if(s == -1)
{
perror("socket() failed\n");
return 2;
}

//bind the socket
my_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
my_addr.sin_port = htons(MY_PORT);
my_addr.sin_family = AF_INET;


if(bind(s, (struct sockaddr*)&my_addr, sizeof(my_addr)) == -1)
{
perror("bind() failed\n");
return 3;
}

//set the address for sending the data
client_addr.sin_addr.s_addr = inet_addr(argv[1]);
client_addr.sin_port = htons(PORT);
client_addr.sin_family = AF_INET;

while(1)
{
FD_ZERO(&rfds);
FD_SET(s, &rfds);
FD_SET(0, &rfds);

max = s;

select(max + 1, &rfds, NULL, NULL, NULL);
size_myaddr = sizeof(my_addr);

if(FD_ISSET(s, &rfds))
{
bytes = recvfrom(s, buffer, sizeof(buffer) -1, 0, (struct sockaddr*)&my_addr, &size_myaddr);
if(bytes == -1)
{

perror("recv() from socket failed\n");
return 4;
}

buffer[bytes] = '\0';

printf("\n[new message]: %s\n", buffer);
}
else if(FD_ISSET(0, &rfds))
{
fgets(buffer, BUF_SIZE, stdin);
bytes = sendto(s, buffer, strlen(buffer), 0, (struct sockaddr*)&client_addr, sizeof(client_addr));
if(bytes == -1)
{
perror("sendto() failed\n");
return 5;
}
}
else
{
printf("error\n");
}
}
close(s);
}
 
Zurück