PDA

Visualizza la versione completa : [C] Sockets, problemi ed info


PaTeR non PeTeR
04-04-2005, 18:15
Ciao raga... mi stavo esercitando con le soclets... ho realizzato un programmino server-side, però non lo ho ancora testato anche perchè devo sviluppare il client... uso il protocollo TCP con IPv4



/************************************************** ***********************************/
/********* PaTeR - New Scripting Generation *********/
/********* Socket Script Example - Function: Server *********/
/************************************************** ***********************************/

// Including required headers
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <stdio.h>
#include <unistd.h>

// Constants
#define MAX_MSG 1024
#define PORT 1991
#define PROTOCOL PF_INET
#define TYPE SOCK_STREAM
#define FAMILY AF_INET

// Functions:
int main();

// Starting Script
main()
{
// Initializing Socket structures
struct sockaddr_in cliAddr, servAddr;

// Init buffer for line to display
char line[MAX_MSG];

// Opening a socket stream: int socket(int domain, int type, int protocol)
int sockfd = socket(PROTOCOL, TYPE, 0);

// Control for incoming socket
if(sockfd <= 0) perror("Cannot create socket");

// Adjusting bind configuration, modifying struct variables
servAddr.sin_family = FAMILY;
servAddr.sin_addr.s_addr = htonl(INADDR_ANY);
servAddr.sin_port = htons(PORT);

// Assign a local address to a socket: int bind(int sockfd, const struct sockaddr *serv_addr, socklen_t addrlen)
int bindc = bind(sockfd, (struct sockaddr *) &servAddr, sizeof(servAddr));

// Control for bind
if(bindc < 0) perror("Cannot bind socket");

// Start 'passive socket': int listen(int sockfd, int backlog)
int listenc = listen(sockfd, 5);

// Control for incoming socket
if(listenc < 0) perror("Cannot start 'passive socket'");

// Start an infinite loop
while(1)
{
// Defining cliAddr size in cliLen
int cliLen = sizeof(cliAddr);

// Accept connection
int ccept = accept(sockfd, (struct sockaddr *) &cliAddr, &cliLen);

// If cannot accept connection
//if(ccept < 0) perror("Cannot accept connection ");

// Receive data
int result = recv(ccept, line, MAX_MSG, 0);

// Control for received data and print something
if(result == 0)
{
// Client closed connection
perror("Connection closed by Client");
}
else
{
if(result < 0)
{
// Cannot receive data
// perror("Cannot receive Data");
}
else
{
// Data received: Showing it
printf("Data received: %s", line);
}
}
}
}



la compilazione è ok, e va senza errori...
dite che va bene??

Ho cercato di usare IPv6 solo che mi dava alcuni errori mentre cerfavo di definire sin6_addr.in6_addr, con htonl(INADDR_ANY) mi diceva che i tipi erano incompatibili... dopo proverò con in6addr_any. intanto che mi dite? è un buon inizio per un dilettante come me? un esempio di client è facile da realizzare? grazie :D

Xadoom
04-04-2005, 19:14
Qui trovi una guida passo passo, alla fine c'è il codice completo, poi ampliarlo per fargli fare quello che vuoi è facile:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winsock/winsock/getting_started_with_winsock.asp
:ciauz:

PaTeR non PeTeR
04-04-2005, 19:35
Originariamente inviato da Xadoom
Qui trovi una guida passo passo, alla fine c'è il codice completo, poi ampliarlo per fargli fare quello che vuoi è facile:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winsock/winsock/getting_started_with_winsock.asp
:ciauz: ehm... sono su debian, no win32...

pensavo si capiva dagli headers...

Xadoom
04-04-2005, 19:39
Ops scusa non ho guardato attentamente... :ciauz:

/dev/null
04-04-2005, 20:13
Gl'ho dato un'occhiata veloce e mi pare a posto... Ma finche' non lo provi non te lo posso assicurare :zizi:
L'unica cosa che potresti modificare e' la recv: recv(ccept, line, MAX_MSG, 0);
Se il client ti scrive meno di MAX_MSG il tuo server resta li' fermo come un fagiano ad aspettare... Per evitarlo o setti la socket come non bloccante, o passi alla recv un parametro per renderla non bloccante, o usi qualche funzione apposita tipo la poll/select/pselect/epoll...
Inoltre questo server puo' accettare solo una connessione per volta (se mentre stai lavorando con un client un altro prova a connettersi non ci riuscira'), per evitare questo dovresti forkare il programma o threaddarlo appena ricevi una connessione...

Se comunque e' solo un server grezzo di prova mi sembra perfetto :unz:

:ciauz:

PaTeR non PeTeR
04-04-2005, 21:03
Originariamente inviato da /dev/null
Gl'ho dato un'occhiata veloce e mi pare a posto... Ma finche' non lo provi non te lo posso assicurare :zizi:
L'unica cosa che potresti modificare e' la recv: recv(ccept, line, MAX_MSG, 0);
Se il client ti scrive meno di MAX_MSG il tuo server resta li' fermo come un fagiano ad aspettare... Per evitarlo o setti la socket come non bloccante, o passi alla recv un parametro per renderla non bloccante, o usi qualche funzione apposita tipo la poll/select/pselect/epoll...
Inoltre questo server puo' accettare solo una connessione per volta (se mentre stai lavorando con un client un altro prova a connettersi non ci riuscira'), per evitare questo dovresti forkare il programma o threaddarlo appena ricevi una connessione...

Se comunque e' solo un server grezzo di prova mi sembra perfetto :unz:

:ciauz: hrazie, mi serviva una prova, grazie mille per il commento, ora vedrò di gestirlo con thyread o altro grazie di cuore :D

PaTeR non PeTeR
04-04-2005, 22:34
Okay... ho sviluppato un client... solo che non mi ritorna niente, anche perchè su SEND ho trovato solo un piccolo esempio e non una guida + approfondita... in più il server non mi ritorna niente...


// Including required headers
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <stdio.h>
#include <unistd.h>

// Constants
#define MAX_MSG 1024
#define PORT 1991
#define PROTOCOL PF_INET
#define TYPE SOCK_STREAM
#define FAMILY AF_INET

int main (int argc, char *argv[])
{
// Variables and Structures
struct sockaddr_in localAddr, servAddr;
struct hostent * host;

// Opening a socket stream: int socket(int domain, int type, int protocol)
int sockfd = socket(PROTOCOL, TYPE, 0);

// Control for incoming socket
if(sockfd <= 0) perror("Cannot create socket");

// Adjusting variables in structure - local
localAddr.sin_family = FAMILY;
localAddr.sin_addr.s_addr = htonl(INADDR_ANY);
localAddr.sin_port = htons(1990);

// Assign a local address to a socket: int bind(int sockfd, const struct sockaddr *serv_addr, socklen_t addrlen)
int bindc = bind(sockfd, (struct sockaddr *) &localAddr, sizeof(localAddr));

// Control for bind
if(bindc < 0) perror("Cannot bind socket");

// Adjusting variables in structure - server
host = gethostbyname("127.0.0.1");
servAddr.sin_family = host->h_addrtype;
servAddr.sin_port = htons(PORT);

// Connecting to server socket: int connect(int sockfd, const struct sockaddr *servaddr, socklen_t addrlen)
int connectc = connect(sockfd, (struct sockaddr *) &servAddr, sizeof(servAddr));

// Control for bind
if(connectc < 0) perror("Cannot connect to socket");

// Sending data to server: int send(int sockfd, const struct sockaddr *servaddr, socklen_t addrlen);
int sendc = send(sockfd, "test", strlen("test") + 1, 0);

// Control for bind
if(sendc < 0) perror("Cannot send data to socket");
}


Voi che dite?

PaTeR non PeTeR
05-04-2005, 15:21
up

PaTeR non PeTeR
06-04-2005, 20:30
Raga... ho visto che l'applicazione server si sukkia un sacco di memo col while(1)...

come posso ovviare il problema????

Ho reso la socket non-bloccante, può bastare??? che devo fare? :cry:

Loading