Witam wszystkich.
Mam taki problem z przesyłaniem danych a mianowicie jak klient podłączy się do serwera to serwer wysyła komunikat do klienta "Podlaczyles sie do serwera" i tak powinno byc ale po pobraniu danych od klienta "recv(gniazdo, buf, 250, 0)" serwer już nie che wysłać do klienta nic zawiesza sie wszystko dopóki nie wyłączę klienta.
Mam plik "serwer" taki :
#include "class.h"
#define MYPORT 5555 // port, z którym będą się łączyli użytkownicy
#define BACKLOG 10
using namespace std;
// wyszukuja martwe procesy
void sigchld_handler(int s)
{
while(wait(NULL) > 0);
}
//######################################################
string IntToStr(int var) {
std::string s;
std::stringstream out;
out << var;
s = out.str();
return s;
}
int main(){
// Klasy
CSQL sql;
//Podziel podz;
Exp exp;
int server, gniazdo,polecenie=0;
unsigned int dlugosc;
struct sockaddr_in moj_adres; //utworzenie struktury adres typu sockaddr_in
struct sockaddr_in adres_klienta;
socklen_t sin_size;
sin_size = sizeof(struct sockaddr_in);
int yes=1;
struct sigaction sa;
char *msg, *wynik;
char buf[250];
string dane,dane2;
vector<string> podzielone;
bool odebrano = false;
string query,imie,nazwisko;
char *pol;
MYSQL_RES* res;
MYSQL_ROW row, end_row;
unsigned long *lengths;
unsigned int num_fields;
size_t wielkosc;
moj_adres.sin_family = AF_INET; //adresy internetowe
moj_adres.sin_port = htons(MYPORT);
moj_adres.sin_addr.s_addr = INADDR_ANY; // przypisz do gniazda domyslny adres IP
memset(&(moj_adres.sin_zero), '\0', 8);
if ((server = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
perror("BLAD funkcji socket !");
exit(1);
}
if (setsockopt(server, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1) {
perror("BLAD funkcji setsockopt !");
exit(1);
}
if (bind(server, (struct sockaddr *)&moj_adres, sizeof(struct sockaddr)) == -1) {
perror("BLAD w dowiazaniu numeru portu do serwera !");
exit(1);
}
if (listen(server, BACKLOG) == -1) {
perror("BLAD podczas tworzenia kolejki połaczeń !");
exit(1);
}
//zabiajmy martwe procesy
sa.sa_handler = sigchld_handler; // zbierz martwe procesy
sigemptyset(&sa.sa_mask);
sa.sa_flags = SA_RESTART;
if (sigaction(SIGCHLD, &sa, NULL) == -1) {
perror("sigaction");
exit(1);
}
printf("\033[01;34m Czekanie na polaczenie klienta \033[00m\n");
// obslucha polaczoonych klientow
while(1) {
sin_size = sizeof(struct sockaddr_in);
if ((gniazdo = accept(server, (struct sockaddr *)&adres_klienta, &sin_size)) == -1) {
perror("accept");
continue;
}
printf("\n\tNawiazano połaczenie z %s:%d\n",inet_ntoa(adres_klienta.sin_addr),ntohs(adres_klienta.sin_port));
if(!fork()){
//close(server); //zamykanie gniazda nasluchu
msg = "\033[01;35m Podlaczyles sie do serwera \033[00m\n";
if (send(gniazdo,msg , strlen(msg), 0) == -1) perror("send");
}
//####################################################################]
//######### POBIERAMY DANE OD KLIENTA ########################################
while(recv(gniazdo, buf, 250, 0) > 0)
{
dane.append(buf);
odebrano = true;
}
dane = dane.substr(0,1);// wycinanie z lancucha 1 znaków
if(odebrano){
if(dane == "p") polecenie = 2;
if(dane == "z") polecenie = 1;
cout << "\n\n\t\t "<<dane << "\n\n\n\t\t "<<polecenie<< "\n\n\n\t\t ";
switch(polecenie){
case 1:
// laczenie z baza danych
sql.Connect("localhost", "test", "test", "test",3306);
exp.Split(dane," ", podzielone);
wielkosc =podzielone.size();
cout << "\n wielkosc wektora : " << wielkosc;
for(size_t i = 0; i < podzielone.size()-1; i++) {
imie = podzielone.at(i);
i++;
nazwisko =podzielone.at(i);
cout << "\n " << imie << " " << nazwisko ;
query = "INSERT INTO `cpp` VALUES ( NULL , '"+imie+"', '"+nazwisko+"')";
sql.Query(query); // zapisywanie do bazy danych
//cout << "\n Zaptanie " << query;
}
dane.clear();
podzielone.clear();
sql.zamkni_mysql();//Zamykamy polaczenie z mysql
break;
case 2:
// laczenie z baza danych
sql.Connect("localhost", "test", "test", "test",3306);
query = "SELECT * FROM `cpp`";
res=sql.Query(query); // zapisywanie do bazy danych
if (res)
{
num_fields = mysql_num_fields(res); // liczba pol w wersie;
while ( (row = mysql_fetch_row(res)) )
{
lengths = mysql_fetch_lengths(res);
// odbieranie
for(int i = 0; i < num_fields; i++)
{
//printf("[%.*s] ", (int) lengths[i], row[i] ? row[i] : "NULL");// wyswietla nr oraz zawartosc
dane2 += row[i];
dane2 += " ";
}
dane2 += "\n";
//printf("\n");
}
//wysylanie do klienta
//######################################################################
//TEGO JUZ NIE WYSYLA I TU MAM PROBLEM ALE NIE WIM CZY TO WINA SERWERA CZY KLIENTA
if(!fork()){
//close(server); //zamykanie gniazda nasluchu
if (send(gniazdo,dane2.c_str() , strlen(dane2.c_str()), 0) == -1) perror("send");
//close(gniazdo);
}
//#####################################################################
}
sql.zamkni_mysql();//Zamykamy polaczenie z mysql
}
odebrano = false;
}
}
return 0;
}
i Klienta :
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <netdb.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <iostream>
#include <fstream>
#include <vector>
using namespace std;
typedef vector<string> string_vector_type;
#define PORT 5555 // port, z którym klient będzie się łączył
#define MAXDATASIZE 100 // maksymalna ilość dancyh, jaką możemy otrzymać na raz
// Funkcja do rozdzielania
//###################################################################################
void Split(const string& text, const string& separators, string_vector_type &words) {
size_t n = text.length ();
size_t start = text.find_first_not_of (separators);
while (start < n) {
size_t stop = text.find_first_of (separators, start);
if (stop > n) stop = n;
words.push_back (text.substr (start, stop-start));
start = text.find_first_not_of (separators, stop+1);
}
}
// Funkcja do laczenia
//############################################################
// ######### COS JAKI IMPLODE W PHP #################################
string implode( const string &glue, string_vector_type &pieces )
{
string a;
int leng=pieces.size();
for(int i=0; i<leng; i++)
{
a+= pieces[i];
if ( i < (leng-1) )
a+= glue;
}
return a;
}
//####################################################################
int main(int argc, char *argv[])
{
int gniazdo, numbytes;
char buf[250];
string dane;
struct hostent *he;
struct sockaddr_in adres_klienta; // informacja o adresie osoby łączącej się
fstream plik; //wysyłany plik
//char danezpliku; //nazwa pliku do wysłania
int ile,i; //ilosc znaków w pliku do wysłania
int len, bytes_sent;
string_vector_type lines;
char *linia;
printf("\n\t+------------------------------------------------+");
printf("\n\t Client ver.0.1");
printf("\n\t");
printf("\n\t Autor: XXXXXXX");
printf("\n\t+------------------------------------------------+\n\n");
if (argc != 3) {
fprintf(stderr,"Uzyj: klient hostname p lub klient hostname z\n");
exit(1);
}
if ((he=gethostbyname(argv[1])) == NULL) { // pobierz informacje o hoście
perror("gethostbyname");
exit(1);
}
if ((gniazdo = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
perror("socket");
exit(1);
}
adres_klienta.sin_family = AF_INET; // host byte order
adres_klienta.sin_port = htons(PORT); // short, network byte order
adres_klienta.sin_addr = *((struct in_addr *)he->h_addr);
memset(&(adres_klienta.sin_zero), '\0', 8); // wyzeruj resztę struktury
if (connect(gniazdo, (struct sockaddr *)&adres_klienta,
sizeof(struct sockaddr)) == -1) {
perror("connect");
exit(1);
} else printf("%s\n", "Połączono...");
printf("%s", "\nWysyłanie danych do servera.");
dane = argv[2];
dane += "\0";
cout <<" \nDane z pliku:\n"<< dane <<endl;
// Wysylanie danych do serwera
if (send(gniazdo,dane.c_str() , strlen(dane.c_str()), 0) == -1) perror("send");
//##############################################
// POBIERANIE KOMUNIKATU O POLACZENIU
if ((numbytes=recv(gniazdo, buf, 250, 0)) == -1) {
perror("recv");
exit(1);
} else {
buf[numbytes] = '\0';
printf("Komunikat: %s",buf);
}
//##############################################
// ODBIERANIE LISTY NAZWISK
if ((numbytes=recv(gniazdo, buf, 250, 0)) == -1) {
perror("recv");
exit(1);
} else {
buf[numbytes] = '\0';
printf("Komunikat: %s",buf);
}
close(gniazdo);
return 0;
}
</cpp>