Pular para o conteúdo

Programar em Socket

Responder tópico
  • Denunciar
  • Indicar

13. Re: Programar em Socket

Enviado em 19/05/2008 - 12:17h

Pois é esses são os códigos que estou usando para enviar mensagens normais de texto. Agora quero implementar para o cliente enviar arquivo e o servidor receber e ler o arquivo.

Responder tópico

14. Me ajudem!

Enviado em 19/05/2008 - 12:18h

é tipo fazer ações no servidor que o cliente requisita! Acho q é isso!

15. cara

Enviado em 19/05/2008 - 13:42h

agora to um poco enrolado, mas se der hj mesmo verifico os arquivos e faço uma alteração para o seu programa transmitir um arquivo. Ai ja posto aqui. Abs

16. Tutorial e Codigos de Socket

Enviado em 19/05/2008 - 16:49h

Olha ai um tutorial e codigos que achei na net sobre socket, me ajudou muito:

Tutorial ensinando socket:
http://www.dicas-l.com.br/dicas-l/20041219.php

Codigos referidos pelo Alessandro no tutorial:
http://linuxgazette.net/issue74/misc/tougher/

Já passei por esse perrengue de ter que aprender socket no meu trampo, mas não achava nada na net.
Até q fussei tanto e consegui achar, alem do tutorial que achei rapidin, os codigos referidos no tutoria q não estavam completos, o q me fazia ficar doido por não ta entendendo nada.

Bem, espero ter ajudado.

17. Afe Stremer

Enviado em 19/05/2008 - 17:22h

"como um código fala mais que mil palavras"

Tu sempre tem uma carta na manga...muleque do capeta...:D

uadshdsuhsddsah

Abraços!

18. ae cara

Enviado em 19/05/2008 - 18:49h

hj tive um dia até sossegado então implementei aqui no seu código uma transferencia de arquivos usando uuencode.
Como fiz meio na correria não sei se ta tudo 100%, mas funcionou belezinha. Logico, precisa fazer somente pelo caminho feliz, e ta aceitando no maximo 1Mb de buffer (precisa implementar o buffer dinamico) alem de implementar mais coisas (lógico), mas como fiz no corre ja da pra vc ter uma boa ideia e ver funcionando e melhorar o código.
As rotinas de uuencode baixei da web e dei uma adaptada pois não tinha nenhum código facil aqui.
O resto implementei encima do seu codigo.
Não sei se tem algum estouro de buffer, pois como falei, a ideia foi te mostrar como funciona, pois fiz agora no final do dia.

Primeiro salve o uuencode.h

------ uuencode.h----

/*
* UUEncode/UUDecode
*
* Lib usando somente ANSI C
*/

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

/* CRC */
unsigned short CRC = 0x0000;

/* Tabela CRC */
static unsigned short crctab[256] = {
0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7,
0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef,
0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6,
0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de,
0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485,
0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d,
0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4,
0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc,
0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823,
0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b,
0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12,
0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a,
0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41,
0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49,
0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70,
0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78,
0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f,
0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067,
0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e,
0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256,
0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d,
0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c,
0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634,
0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab,
0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3,
0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a,
0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92,
0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9,
0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1,
0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8,
0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0
};

#define updcrc(cp, crc) ( crctab[((crc>>8)&0x0FF)]^(crc<<8)^(cp&0x0FF) )

/* Encode de char */
char ENC(char ch) {
ch = (ch & 0x03F) + ' ';
switch (ch)
{
case ' ' : ch = 'm';
break;
case '[' : ch = 'd';
break;
case '\\' : ch = 'e';
break;
case ']' : ch = 'f';
break;
case '^' : ch = 'g';
break;
case '\'' : ch = 'h';
break;
}
return(ch);
}

/* Decode de char */
char DECN(char ch) {
switch (ch) {
case 'm' : ch = ' ';
break;
case 'd' : ch = '[';
break;
case 'e' : ch = '\\';
break;
case 'f' : ch = ']';
break;
case 'g' : ch = '^';
break;
case 'h' : ch = '\'';
break;
}
ch = (ch - ' ') & 0x03F;
return(ch);
}

/* Aqui decodificamos 4 chars */
char * outdec (char * p) {
int c1, c2, c3, c4;
char * pret;
char * ret = (char *) malloc(sizeof(char) * 5);
pret = ret;
c1 = *p >> 2;
c2 = (*p << 4) & 0x30 | (p[1] >> 4) & 0x0F;
c3 = (p[1] << 2) & 0x3C | (p[2] >> 6) & 0x03;
c4 = p[2] & 0x3F;

*ret = ENC(c1);
ret++;
*ret = ENC(c2);
ret++;
*ret = ENC(c3);
ret++;
*ret = ENC(c4);
ret++;
*ret = 0;
return pret;
}

/* Aqui decodificamos */
char * outdec2(char * p, char * out, int n) {
int c1, c2, c3;
char * ret;
ret = out;
c1 = DECN(*p) << 2 | DECN(p[1]) >> 4;
c2 = DECN(p[1]) << 4 | DECN(p[2]) >> 2;
c3 = DECN(p[2]) << 6 | DECN(p[3]);
if (n >= 1) { *ret = c1; ret++; *ret = 0; CRC = updcrc(c1,CRC); }
if (n >= 2) { *ret = c2; ret++; *ret = 0; CRC = updcrc(c2,CRC); }
if (n >= 3) { *ret = c3; ret++; *ret = 0; CRC = updcrc(c3,CRC); }
return ret;
}

/* Encode de string */
char * encode(char * in, int size) {
char * out = (char *) malloc((sizeof(char) * size) * 2);
if (out == NULL) {
printf("ERRO na alocacao\n");
exit(-1);
}
char * pout;
char * crcStr;
char * decChar;
char * pdecChar;
char buf[80];
int i, n, cor;

pout = out;
cor = 0;
for (;;) {
n = fr(in, buf, 45, size, cor);
cor += 45;
*pout = ENC(n);
pout++;
for (i = 0; i < n; i++) {
CRC = updcrc(buf[i], CRC);
}
for (i=0; i<n; i += 3) {
decChar = (char *) outdec(&buf[i]);
pdecChar = decChar;
*pout = *decChar; pout++; decChar++;
*pout = *decChar; pout++; decChar++;
*pout = *decChar; pout++; decChar++;
*pout = *decChar; pout++; decChar++;
free(pdecChar);
}
*pout = '\n';
pout++;
*pout = 0;
if (n <= 0) break;
}
crcStr = (char *) malloc(sizeof(char) * 45);
sprintf(crcStr, "CRC= %04X\n", CRC);
strcat(out, crcStr);
strcat(out, "end\n");
return out;
}

/* Decode de string */
int decode(char * in, char * out, int size) {
char * pin;
char * pout;
char buf[80];
char *bp;
int n;
int i;
int tam;
pin = in;
pout = out;

tam = 0;
for (;;) {
for (i = 0; i < 80; i++) {
if (*pin != '\n' && *pin != '\r') {
buf[i] = *pin;
pin++;
} else {
pin++;
buf[i] = 0;
break;
}
}

n = DECN(buf[0]);
if (n <= 0) break;
tam += n;

bp = &buf[1];
while (n > 0) {
pout = outdec2(bp, pout, n);
bp += 4;
n -= 3;
}
}
*pout = 0;
return tam;
}

/* Para leitura de buffer */
int fr(char * fd, char * buf, int cnt, int size, int cor) {
int c, i;
char * pfd = fd;
for (i = 0; i < cor; i++) {
pfd++;
}
for (i = 0; i < cnt; i++) {
c = *pfd;
pfd++;
if ((cor + i + 1) > size) return(i);
buf[i] = c;
}
return (cnt);
}


------ fim uuencode.h----

19. agora o cliente.c

Enviado em 19/05/2008 - 18:49h

----- cliente.c -----
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdlib.h>
#include <string.h>
#include "uuencode.h"

int main(int argc, char *argv[]) {
int sockdescr;
int numbytesrecv;
struct sockaddr_in sa;
struct hostent *hp;
char buf[BUFSIZ+1];
char *host;
char *dados;
char *arquivo;
FILE * in;
char * conteudoArquivo;
char * pconteudoArquivo;
int tamanhoArquivo;
char c;
char * arquivoEncode;
char * headerEncode;
int tamanhoEncode;

if(argc != 4) {
puts("Uso correto: <cliente> <nome-servidor> <porta> <arquivo>");
exit(1);
}

host = argv[1];
arquivo = argv[3];

if((hp = gethostbyname(host)) == NULL){
puts("Nao consegui obter endereco IP do servidor.");
exit(1);
}

bcopy((char *)hp->h_addr, (char *)&sa.sin_addr, hp->h_length);
sa.sin_family = hp->h_addrtype;

sa.sin_port = htons(atoi(argv[2]));

if((sockdescr=socket(hp->h_addrtype, SOCK_STREAM, 0)) < 0) {
puts("Nao consegui abrir o socket.");
exit(1);
}

printf("numero de bytes %d\n", sizeof sa);
if(connect(sockdescr, (struct sockaddr *) &sa, sizeof sa) < 0) {
puts("Nao consegui conectar ao servidor");
exit(1);
}

// Aqui transmitimos o arquivo
// Primeiro devemos ler e passar o uuencode
if ((in = fopen(arquivo, "rb")) == NULL) {
puts("Nao foi possivel abrir o arquivo");
exit(1);
}

// Agora lemos o arquivo (Vamos ler da forma mais [*****] para ficar claro)
// Depois você pode implementar um buffer mais inteligente
// Vamos também alocar de maneira fixa 1 Mb, não serão aceitos arquivos maiores
// Para isto você deve implementar o realloc ou do jeito que quiser
conteudoArquivo = malloc(sizeof(char) * 1024 * 1024);
pconteudoArquivo = conteudoArquivo;
tamanhoArquivo = 0;
while (!feof(in)) {
c = getc(in);
if (!feof(in)) {
*pconteudoArquivo = c;
pconteudoArquivo++;
tamanhoArquivo++;
}
}
*pconteudoArquivo = 0;
fclose(in);

// Faz o uuencode
headerEncode = (char *) malloc(sizeof(char) * 1024);
sprintf(headerEncode, "...begin... 777 %s\n", arquivo);
arquivoEncode = encode(conteudoArquivo, tamanhoArquivo);
tamanhoEncode = strlen(arquivoEncode) + strlen(headerEncode);

// Vamos montar um (mini header)
dados = (char *) malloc(sizeof(char) * 1024);
sprintf(dados, "ARQUIVO: [%s] - TAMANHO: [%d]\n\n", arquivo, tamanhoEncode);

if(write(sockdescr, dados, strlen(dados)) != strlen(dados)){
puts("Nao consegui mandar os dados");
exit(1);
}

// Agora vamos mandar o arquivo
if(write(sockdescr, headerEncode, strlen(headerEncode)) != strlen(headerEncode)){
puts("Nao consegui mandar o headerEncode");
exit(1);
}
if(write(sockdescr, arquivoEncode, strlen(arquivoEncode)) != strlen(arquivoEncode)){
puts("Nao consegui mandar o arquivoEncode");
exit(1);
}

// Nao vamos considerar a conversa toda por enquanto
//read(sockdescr, buf, BUFSIZ);
//printf("Sou o cliente, recebi: %s\n", buf);

close(sockdescr);

// Limpamos da memoria
free(conteudoArquivo);
free(arquivoEncode);
exit(0);
}
---- fim cliente.c ---

20. e o servidor.c

Enviado em 19/05/2008 - 18:50h

----- servidor.c ----
#include <stdio.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdlib.h>
#include <string.h>
#include "uuencode.h"

#define TAMFILA 5
#define MAXHOSTNAME 30

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

int s, t;
unsigned int i;
char buf [BUFSIZ + 1];
struct sockaddr_in sa, isa;
struct hostent *hp;
char localhost [MAXHOSTNAME];
char * conteudoArquivo;
int bufLido = 0;
int bufTotal = 0;

signal();
if (argc != 2) {
puts("Uso correto: servidor <porta>");
exit(1);
}

gethostname (localhost, MAXHOSTNAME);
if ((hp = gethostbyname( localhost)) == NULL){
puts ("Nao consegui meu proprio IP");
exit (1);
}

sa.sin_port = htons(atoi(argv[1]));
sa.sin_family = hp->h_addrtype;
bcopy ((char *) hp->h_addr, (char *) &sa.sin_addr, hp->h_length);

if ((s = socket(hp->h_addrtype,SOCK_STREAM,0)) < 0){
puts ("Nao consegui abrir o socket");
exit ( 1 );
}

if (bind(s, (struct sockaddr *) &sa,sizeof(sa)) < 0){
puts ("Nao consegui fazer o bind");
exit ( 1 );
}
listen (s, TAMFILA);

while (1){
i = sizeof(sa);
if ((t=accept(s, (struct sockaddr *) &isa,&i))<0){
puts ("Nao consegui fazer conexao");
exit (1);
}
read(t, buf, BUFSIZ);

// Vamos somente considerar o caminho feliz e que aqui veio todo o arquivo
printf("Sou o servidor, recebi a mensagem----> %s\n", buf);
// Precisamos ler o buffer total e o nome do arquivo
char * posBufIni = strstr(buf, "TAMANHO: [");
if (posBufIni == NULL) {
printf("Erro ao ler caminho feliz 1.\n");
exit(-1);
}
char * posBufFim = strstr(posBufIni + 10, "]");
if (posBufFim == NULL) {
printf("Erro ao ler caminho feliz 2.\n");
exit(-1);
}
char * tamStr = (char *) malloc(sizeof(char) * 1024);
if (tamStr == NULL) {
printf("Falta de memoria.\n");
exit(-1);
}
int tamanhoDados = strlen(posBufIni) - strlen(posBufFim) - 10;
strncpy(tamStr, posBufIni + 10, tamanhoDados);
tamStr[tamanhoDados] = 0;
bufTotal = atoi(tamStr);
printf("Buffer Total: %d\n", bufTotal);

conteudoArquivo = malloc(sizeof(char) * 1024 * 1024);
*conteudoArquivo = 0;
memset(buf, 0x00, BUFSIZ + 1);
read(t, buf, BUFSIZ);
strcpy(conteudoArquivo, buf);
bufLido = strlen(conteudoArquivo);
int mode;
char dest[128];
sscanf(conteudoArquivo, "...begin... %o %s", &mode, dest);
bufTotal = bufTotal - strlen(conteudoArquivo);
strcpy(conteudoArquivo, "");
while (bufLido < bufTotal) {
memset(buf, 0x00, BUFSIZ + 1);
read(t, buf, BUFSIZ);
strcat(conteudoArquivo, buf);
bufLido = strlen(conteudoArquivo);
}

// Agora devemos gravar o conteudo
conteudoArquivo[bufTotal] = 0;
FILE * fout;
fout = fopen(dest, "wb");
if (fout == NULL) {
printf("Erro ao criar arquivo: %s\n", dest);
exit(4);
}

char * out = (char *) malloc((sizeof(char) * bufTotal) * 2);
int tam2 = decode(conteudoArquivo, out, bufTotal);
for (i = 0; i < tam2; i++) {
putc(out[i], fout);
}
fclose(fout);
printf("Gerou arquivo: %s\n", dest);

//Nao vamos devolver nada por enquanto
write(t,"OK\n", 3);
close(t);
}

}
----- fim servidor.c ----

21. ae

Enviado em 19/05/2008 - 18:57h

testei aqui e o vol não zuou nada.
Para compilar, crie 2 diretórios (para ter certeza do envio do arquivo) e então copie o uuencode.h em ambos e compile com gcc.
Depois inicie o servidor por ex:
( O bind precisa de root )
# sudo ./servidor 666
Depois copie um arquivo zip ou qualquer outro para o diretorio do cliente.
Então:
# ./cliente localhost 666 arquivo.zip

O servidor deverá receber o arquivo.
Depois entre no diretório do servidor e:
# file arquivo.zip
Vera que é um zip de verdade.
Então pode lidar com o arquivo.

Enfim, o repito, como código vale mais que mil palavras, só olhar o código, ver como funciona e modificar ao seu gosto.

Espero que ajude!

ABS

22. Agradecimento!

Enviado em 21/05/2008 - 13:07h

Valeu stremer. Muito obrigado! Vou compilar sim to sem muyito tempo por isso demorei a postar. Assim que compilar vou te responder. Mas obrigado mesmo!

23. Alguém sabe!

Enviado em 26/05/2008 - 17:58h

comunicação entre dois programas em C (servidor - cliente), para a troca de strings.

24. Valeu!

Enviado em 26/05/2008 - 18:14h

Funcionou stremer. Blz! Vou dar uma estuda para ver se aprendo mais. Muito obrigado pela ajuda!

Responder tópico

Responder tópico

Entre na sua conta para responder.

Fazer login para responder