Torna indietro   Hardware Upgrade Forum > Software > Programmazione

Hisense M2 Pro: dove lo metti, sta. Mini proiettore laser 4K per il cinema ovunque
Hisense M2 Pro: dove lo metti, sta. Mini proiettore laser 4K per il cinema ovunque
Dal salotto al giardino, il nuovo proiettore laser di Hisense promette esperienze cinematografiche in qualsiasi contesto: qualità d’immagine, semplicità d’uso, versatilità e prezzo competitivo il suo poker d'assi
Lenovo ThinkPad X1 2-in-1 G10 Aura Edition: il convertibile di classe
Lenovo ThinkPad X1 2-in-1 G10 Aura Edition: il convertibile di classe
La flessibilità di configurazione è il punto di forza di questo 2-in-1, che ripropone in un form factor alternativo tutta la tipica qualità dei prodotti Lenovo della famiglia ThinkPad. Qualità costruttiva ai vertici, ottima dotazione hardware ma costo che si presenta molto elevato.
Intervista a Stop Killing Games: distruggere videogiochi è come bruciare la musica di Mozart
Intervista a Stop Killing Games: distruggere videogiochi è come bruciare la musica di Mozart
Mentre Ubisoft vorrebbe chiedere agli utenti, all'occorrenza, di distruggere perfino le copie fisiche dei propri giochi, il movimento Stop Killing Games si sta battendo per preservare quella che l'Unione Europea ha già riconosciuto come una forma d'arte. Abbiamo avuto modo di parlare con Daniel Ondruska, portavoce dell'Iniziativa Europa volta a preservare la conservazione dei videogiochi
Tutti gli articoli Tutte le news

Vai al Forum
Rispondi
 
Strumenti
Old 31-01-2010, 19:12   #1
Mulder90
Senior Member
 
L'Avatar di Mulder90
 
Iscritto dal: Aug 2008
Città: Firenze
Messaggi: 317
[C] WinSock, creazione semplice chat

Ciao a tutti.
Ultimamente mi sono messo a studiare i socket e ho fatto un client e un server il cui codice è quello sotto.
Il client riesce a scrivere messaggi al server che li riceve correttamente.
Volevo creare però qualcosa di più simile ad una chat dove il programma sia in grado di ricevere e spedire messaggi.
Dritte su come iniziare???

CLIENT:
Codice:
#include <stdio.h>
#include <winsock2.h>
#define close closesocket

int init_winsock(void)
{
    WSADATA wsadata;
    int err;
    err=WSAStartup(MAKEWORD(2,2),&wsadata);
    if(err!=0)
    return 0;
    else
    return 1;
}

int main()
{
	int sock, port;
	char ip[17];
    char buffer[256];
	struct sockaddr_in saddr;

	if(!init_winsock())
	{
		printf("Errore durante l'inizializzazione di winsock2.\n");
	    return -1;
	}

	printf("Server Ip: ");
	scanf("%16s", ip);

	printf("Server Port: ");
	scanf("%d", &port);

	if((sock = socket(PF_INET, SOCK_STREAM, 0)) < 0)
	{
		printf("Errore durante la creazione del socket.\n");
		return -1;
	}

	saddr.sin_family = PF_INET;
	saddr.sin_addr.s_addr = inet_addr(ip);
	saddr.sin_port = htons(port);

	if(connect(sock, (struct sockaddr *) &saddr, sizeof(saddr)) < 0)
	{
		printf("Errore durante la connessione a %s:%d\n", ip, port);
		return -1;
	}

	printf("Connessione correttamente stabilita con %s:%d\n", ip, port);
	printf("Ora e' possibile digitare messaggi da inviare al server\n\n");

	do {
		printf("> ");
		fgets(buffer,256,stdin);
	}
	while(send(sock, buffer, sizeof(buffer), 0) > 0);

	printf("Connessione persa.\n");
	close(sock);
	WSACleanup();

	return 0;
}
SERVER:
Codice:
#include <stdio.h>
#include <winsock2.h>
#define close closesocket
init_winsock(void)
{
    WSADATA wsadata;
    int err;
    err=WSAStartup(MAKEWORD(2,2),&wsadata);
    if(err!=0)
    return 0;
    else
    return 1;
}

int main()
{
	int sock, clientsd, port = 5000;
	char buffer[256];
	struct sockaddr_in saddr;

	if(!init_winsock())
	{
	    printf("Errore durante l'inizializzazione di winsock2.\n");
	    return -1;
	}

	if((sock = socket(PF_INET, SOCK_STREAM, 0)) < 0)
	{
		printf("Errore durante la creazione del socket.\n");
		return -1;
	}

	saddr.sin_family = PF_INET;
	saddr.sin_addr.s_addr = INADDR_ANY;
	saddr.sin_port = htons(port);

	if((bind(sock, (struct sockaddr *) &saddr, sizeof(saddr))) < 0)
	{
		printf("Errore durante il binding del socket.\n");
		return -1;
	}

	if((listen(sock, 1)) < 0)
	{
		printf("Errore durante il settaggio del socket in listening.\n");
		return -1;
	}

	printf("In attesa che un client si connetta...\n");
	clientsd = accept(sock, NULL, NULL);
	printf("Si è connesso un client.\n\n");

	while(recv(clientsd, buffer, 255, 0) > 0)
	{
		printf("%s\a\n", buffer);
	}

	printf("Connessione persa.\n");
	close(sock);
	WSACleanup();

	return 0;
}
Mulder90 è offline   Rispondi citando il messaggio o parte di esso
Old 31-01-2010, 19:59   #2
fero86
Senior Member
 
Iscritto dal: Oct 2006
Città: Roma
Messaggi: 1383
Quote:
Originariamente inviato da Mulder90 Guarda i messaggi
Volevo creare però qualcosa di più simile ad una chat dove il programma sia in grado di ricevere e spedire messaggi.
Dritte su come iniziare???
creare una chat in C usando un socket é relativamente semplice: una volta impostata la connessione col peer basta che realizzi quella che io chiamo una "pompa di I/O", cioé un loop che legge bytes da un file descriptor e li sbatte su un altro. poi fai partire due threads ciascuno dei quali fa girare una pompa di I/O: un thread legge dal file descriptor di stdin e sbatte sul socket, e l'altro legge dal socket e sbatte su stdout. le syscall per realizzare una pompa di I/O sono read e write. da che so io non é indispensabile usare recv e send sui socket, i socket vengono trattati come normali file descriptors e quindi anche read e write funzionano su di essi.

edit - ah, occhio alle modalitá di flush.
fero86 è offline   Rispondi citando il messaggio o parte di esso
Old 31-01-2010, 21:55   #3
Mulder90
Senior Member
 
L'Avatar di Mulder90
 
Iscritto dal: Aug 2008
Città: Firenze
Messaggi: 317
Quote:
Originariamente inviato da fero86 Guarda i messaggi
creare una chat in C usando un socket é relativamente semplice: una volta impostata la connessione col peer basta che realizzi quella che io chiamo una "pompa di I/O", cioé un loop che legge bytes da un file descriptor e li sbatte su un altro. poi fai partire due threads ciascuno dei quali fa girare una pompa di I/O: un thread legge dal file descriptor di stdin e sbatte sul socket, e l'altro legge dal socket e sbatte su stdout. le syscall per realizzare una pompa di I/O sono read e write. da che so io non é indispensabile usare recv e send sui socket, i socket vengono trattati come normali file descriptors e quindi anche read e write funzionano su di essi.

edit - ah, occhio alle modalitá di flush.
potresti essere un po più chiaro? non ho capito molto bene il metodo
Mulder90 è offline   Rispondi citando il messaggio o parte di esso
Old 31-01-2010, 23:42   #4
clockover
Senior Member
 
L'Avatar di clockover
 
Iscritto dal: Oct 2004
Messaggi: 1945
Altrimenti potresti far creare al server due thread (o più dipende da quanti client insieme vuoi far chattare)! Ogni thread riceverà un messaggio dal client e lo manderà in output sull'altro client!
clockover è offline   Rispondi citando il messaggio o parte di esso
Old 01-02-2010, 00:22   #5
fero86
Senior Member
 
Iscritto dal: Oct 2006
Città: Roma
Messaggi: 1383
Quote:
Originariamente inviato da Mulder90 Guarda i messaggi
potresti essere un po più chiaro? non ho capito molto bene il metodo
questa é quella che io chiamo "pompa di I/O" (scritta or ora, codice non testato, spero renda l'idea):
Codice:
void IoPump(int fdSource, int fdSink) {
	const size_t cbBuffer = 0x1000;
	char pBuffer[cbBuffer];
	while (1) {
		ssize_t nResult = read(fdSource, pBuffer, cbBuffer);
		if (nResult < 0) {
			return;
		}
		size_t cbRead = (size_t)nResult;

		size_t cbWritten = 0;
		while (cbWritten < cbRead) {
			nResult = write(fdSink, pBuffer + cbWritten, cbRead - cbWritten);
			if (nResult < 0) {
				return;
			}
			cbWritten += (size_t)nResult;
		}
	}
}
ora immaginati di avere un socket descriptor in una variabile di nome "s" ed immaginati di far partire due thread; uno dei due thread invoca:
Codice:
IoPump(0, s);
e l'altro invoca:
Codice:
IoPump(s, 1);
fine; hai fatto la chat.

Ultima modifica di fero86 : 01-02-2010 alle 00:25.
fero86 è offline   Rispondi citando il messaggio o parte di esso
Old 01-02-2010, 12:43   #6
Mulder90
Senior Member
 
L'Avatar di Mulder90
 
Iscritto dal: Aug 2008
Città: Firenze
Messaggi: 317
Quote:
Originariamente inviato da clockover Guarda i messaggi
Altrimenti potresti far creare al server due thread (o più dipende da quanti client insieme vuoi far chattare)! Ogni thread riceverà un messaggio dal client e lo manderà in output sull'altro client!
su linux la funzione è fork() giusto?su windows?
Mulder90 è offline   Rispondi citando il messaggio o parte di esso
Old 01-02-2010, 12:45   #7
Mulder90
Senior Member
 
L'Avatar di Mulder90
 
Iscritto dal: Aug 2008
Città: Firenze
Messaggi: 317
Quote:
Originariamente inviato da fero86 Guarda i messaggi
questa é quella che io chiamo "pompa di I/O" (scritta or ora, codice non testato, spero renda l'idea):
Codice:
void IoPump(int fdSource, int fdSink) {
	const size_t cbBuffer = 0x1000;
	char pBuffer[cbBuffer];
	while (1) {
		ssize_t nResult = read(fdSource, pBuffer, cbBuffer);
		if (nResult < 0) {
			return;
		}
		size_t cbRead = (size_t)nResult;

		size_t cbWritten = 0;
		while (cbWritten < cbRead) {
			nResult = write(fdSink, pBuffer + cbWritten, cbRead - cbWritten);
			if (nResult < 0) {
				return;
			}
			cbWritten += (size_t)nResult;
		}
	}
}
ora immaginati di avere un socket descriptor in una variabile di nome "s" ed immaginati di far partire due thread; uno dei due thread invoca:
Codice:
IoPump(0, s);
e l'altro invoca:
Codice:
IoPump(s, 1);
fine; hai fatto la chat.
Grazie mille per la spiegazione...appena ho un po di tempo cerco di mettere in pratica
Mulder90 è offline   Rispondi citando il messaggio o parte di esso
Old 01-02-2010, 14:39   #8
fero86
Senior Member
 
Iscritto dal: Oct 2006
Città: Roma
Messaggi: 1383
Quote:
Originariamente inviato da Mulder90 Guarda i messaggi
su linux la funzione è fork() giusto?su windows?
lo standard del C non prevede il multitasking; lo standard POSIX invece si, ma su Windows non é del tutto implementato (la fork ad esempio, per l'appunto, manca perché non é implementabile). se devi fare programmazione concorrente in C non puoi programmare cross-platform, il meglio che puoi fare é usare delle compilazioni condizionali; un'alternativa migliore secondo me é usare la select: non appena uno dei due file descriptors tra 0 e il socket é pronto per la lettura pompi bytes da esso. a quel punto peró non so se puoi usare la IoPump che ti ho scritto sopra, quella l'avevo scritta nell'ipotesi che tu programmassi per un solo sistema.
fero86 è offline   Rispondi citando il messaggio o parte di esso
Old 01-02-2010, 14:40   #9
fero86
Senior Member
 
Iscritto dal: Oct 2006
Città: Roma
Messaggi: 1383
Quote:
Originariamente inviato da Mulder90 Guarda i messaggi
su linux la funzione è fork() giusto?su windows?
comunque, per farla breve: http://msdn.microsoft.com/en-us/libr...53(VS.85).aspx

fero86 è offline   Rispondi citando il messaggio o parte di esso
 Rispondi


Hisense M2 Pro: dove lo metti, sta. Mini proiettore laser 4K per il cinema ovunque Hisense M2 Pro: dove lo metti, sta. Mini proiett...
Lenovo ThinkPad X1 2-in-1 G10 Aura Edition: il convertibile di classe Lenovo ThinkPad X1 2-in-1 G10 Aura Edition: il c...
Intervista a Stop Killing Games: distruggere videogiochi è come bruciare la musica di Mozart Intervista a Stop Killing Games: distruggere vid...
Samsung Galaxy S25 Edge: il top di gamma ultrasottile e leggerissimo. La recensione Samsung Galaxy S25 Edge: il top di gamma ultraso...
HP Elitebook Ultra G1i 14 è il notebook compatto, potente e robusto HP Elitebook Ultra G1i 14 è il notebook c...
'La potenza di 16 core, nel palmo della ...
Windows 10 compie 10 anni, ma il cambiam...
Un altro Pixel 6a ha preso fuoco: la pro...
NVIDIA, ritorno in Cina in grande stile?...
Tutti contro Windows Recall: un altro se...
PlayStation FlexStrike: il sogno di un f...
WhatsApp sorprende tutti: ecco la nuova ...
Addio GTX 1080 Ti: la scheda che ha fatt...
Ex Ilva di Taranto, 'Teslari' contro il ...
Finalmente! Arrivano su OneNote due funz...
Fallisce il progetto segreto del pap&agr...
'Marie', l'AI che curava il cancro: la t...
Giochi per adulti bannati: i gamer in ri...
Meta avrà il suo primo smartwatch...
Colpo di scena Samsung: One UI 8 dice st...
Chromium
GPU-Z
OCCT
LibreOffice Portable
Opera One Portable
Opera One 106
CCleaner Portable
CCleaner Standard
Cpu-Z
Driver NVIDIA GeForce 546.65 WHQL
SmartFTP
Trillian
Google Chrome Portable
Google Chrome 120
VirtualBox
Tutti gli articoli Tutte le news Tutti i download

Strumenti

Regole
Non Puoi aprire nuove discussioni
Non Puoi rispondere ai messaggi
Non Puoi allegare file
Non Puoi modificare i tuoi messaggi

Il codice vB è On
Le Faccine sono On
Il codice [IMG] è On
Il codice HTML è Off
Vai al Forum


Tutti gli orari sono GMT +1. Ora sono le: 14:28.


Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
Served by www3v