tenho 2 programs de socket (um cliente e um servidor)
Estou tentando enviar um video através dele
##########
while 1:
for stream in video.readlines():
#data = struct.pack('>i4sh',count,stream)
count=count+1
connection.send(stream)
#########################
Da maneira acima eu consigo enviar o video e recebo do outro lado sem
nenhum problema, consigo guardar o video em um arquivo ou redirecionar
a saida dele e tocar com o mplayer.
Tentei criar um buffer e fazer a mesma coisa mas não consigo enviar
por socket, já tentei criar um pacote com struct , mas não consegui
enviar ele pelo socket e já tentei criar lista e tupla e enviar, mas
tive o mesmo problema
algo tipo:
for stream in video.readlines():
count+=count
data = [str(count),stream] #tentei usar uma tupla aqui mas também não consegui
connection.send(data)
meus fontes estão em
[1]http://code.google.com/p/flashcrowdsanalyse/source/browse/#svn/trunk/DESENVOLVIMENTO
os arquivos para quem quiser ver o código inteiro são o csnode2.py e o source.py
para rodar eles corretamente é preciso estar com o bootstrap.py rodando também.
Ps: o resto a principio está tudo funcionando o único problema mesmo é
conseguir enviar o stream acompanhado de um ID.
Ps2: tentei fazer algo mais tosco também colocar algo concatenado
junto com o stream
stream = id+'@@@@@@@@@@'+stream
stream = stream.split('@@@@@@@@@@')
sys.stdout.write(stream[1])
Se fizer o teste sem enviar por socket funciona (lendo o arquivo e
redirecionando por mplayer), mas pelo socket ele não funciona também.
#python testecomsplit.py | mplayer -
Se alguém tiver alguma forma de empacotar isto ou enviar a tupla ou
lista, agradeço.
Grato,
Fernando Zank Correa Evangelista
--
"Somos o que repetidamente fazemos, portanto a
excelência não é um feito é um hábito" - Aristóteles
------------------------------------
,-----------------------------------------------------------.
| Antes de enviar um e-mail para o grupo leia: |
| http://www.pythonbrasil.com.br/moin.cgi/AntesDePerguntar |
| E se você é usuário do BOL lembre-se de cadastrar o |
| e-mail do grupo na lista branca do seu sistema anti-spam. |
`-----------------------------------------------------------´Links do Yahoo! Grupos
<*> Para visitar o site do seu grupo na web, acesse:
http://br.groups.yahoo.com/group/python-brasil/
<*> Para sair deste grupo, envie um e-mail para:
python-brasi...@yahoogrupos.com.br
<*> O uso que você faz do Yahoo! Grupos está sujeito aos:
http://br.yahoo.com/info/utos.html
--
Até,
Luciano
<quote>
"Na prática, a teoria é outra!"
</quote>
:wq!
Sou novato em python ainda (nunca usei nenhum dos 2), mas vou dar uma
pesquisada no assunto e tentar resolver com o pickles ou com o shelve
conforme me indicou.
Obrigado,
Fernando Zank Correa Evangelista
2009/4/25 Luciano Rodrigues da Silva <lucro...@gmail.com>:
>
>
> Não dá pra empacotar sua lista ou tupla com pickles ou com shelve?
> Acho que isso resolveria o problema.
>
> --
> Até,
>
> Luciano
>
> <quote>
> "Na prática, a teoria é outra!"
> </quote>
>
> :wq!
>
>
--
"Somos o que repetidamente fazemos, portanto a
excelência não é um feito é um hábito" - Aristóteles
http://docs.python.org/tutorial/inputoutput.html#the-pickle-module
http://docs.python.org/library/pickle.html
http://docs.python.org/library/shelve.html
--
Até,
Luciano
<quote>
"Na prática, a teoria é outra!"
</quote>
:wq!
Só mais uma dica: acho melhor se concentrar no pickle, o formato
gerado pelo shelve pode (podia?) variar entre plataformas...
--
Adam Victor Nazareth Brandizzi
http://brandizzi.googlepages.com/
Acho que isso é para o marshal. pickles e shelves, pelo que li na
documentação, são portaveis.
P.S: Documentação com Sphinx rocks =D
--
Até,
Luciano
<quote>
"Na prática, a teoria é outra!"
</quote>
:wq!
Mas o shelve não escolhe o formato a partir dos disponíveis? Digo,
pode usar dbm, gdbm, bsddb... Pode ser complicado lidar com isso se de
um lado se tem dbm e do outro bsddb, não?
Enfim, eu falo na ignorância mesmo, não sei se ele realmente teria
esse problema, mas gostaria de saber :)
> P.S: Documentação com Sphinx rocks =D
Até!
--
Adam Victor Nazareth Brandizzi
http://brandizzi.googlepages.com/
Olha, eu posso até estar errado, mas pelo que entendo, todas essas são
implementações do dbm. Se vc tiver utilizando um sistema gnu, deve ter
o gdbm, se for bsd seria bsddb, mas todos fazem a mesma coisa.
--
Até,
Luciano
<quote>
"Na prática, a teoria é outra!"
</quote>
:wq!
Bem, bom saber! É mais fácil eu estar enganado ;) Só achei relevante
destacar o ponto que eu achava valer, para o Fernando não ser pego de
surpresa. De qualquer forma, já aprendi algo hoje.
Até!
--
Adam Victor Nazareth Brandizzi
http://brandizzi.googlepages.com/
Pra que tu quer usar isso? Eu vi um monte de respostas, mas eu acho
que o povo não viu que nos teus exemplos tu tá querendo mandar só 2 ou
3 coisas, um id, tamanho e pacote de dados. Isso é o que geralmente se
usa em um protocolo de comunicação, é isso que tu quer implementar? Se
for procure por isso na internet, o jeito mais fácil é usar um pacote
com tamanhos fixos para id e tamanho (por exemplo 4 ou 10 bytes para
cada um) e o payload de dados tem um tamanho variado que é o definito
no campo de tamanho.
Olhe exemplos de uso do asynccore/asyncchat e twisted, existem muitos
muitos exemplos de protocolos de transferencia de dados. Ah e não se
esqueça algo similar ao que tu esta fazendo já acontece no nível de
rede com tcp/ip.
--
Leonardo Santagada
santagada at gmail.com
Leonardo,
Eu preciso só enviar mesmo um id e o dado que nem , ou seja o payload
e o id e possa tratar do outro lado para pegar somente o payload. Vou
verificar o que me indicou também. Dar uma estudada nos protocolos de
transporte.
Mais tarde eu mando de volta aqui os resultados e a maneira como eu
consegui fazer (espero conseguir acabar hoje ehehe)
Grato,
Fernando Zank Correa Evangelista
2009/4/26 Leonardo Santagada <sant...@gmail.com>:
--
"Somos o que repetidamente fazemos, portanto a
excelência não é um feito é um hábito" - Aristóteles
Bem pessoal falei que ia postar a solucao aqui hoje, mas infelizmente
sigo sem sucesso para resolver o problema.
A mais perto que cheguei foi com pickles, mas ainda fica meio estranho ...
Segue abaixo os arquivos que usei para teste
o primeiro eh o servidor e o segundo o cliente
o arquivo 'teste' que estou lendo tinha apenas os numeros de 1-10 no formato
1
2
...
10
Mesmo assim nao consegui receber minha estrutura correta no outro lado
o maximo que funcionou foi receber a estrutura do 1 ao 9, mas outras
vezes recebi a estrutura cortada, somente uns 3 ou 4 numeros.
#################################################3
mport pickle
def PadMsg(msg):
while len(msg) < 1024:
msg=msg+' '
return msg
myHost = ''
myPort = 50007
sockobj = socket(AF_INET, SOCK_STREAM)
sockobj.bind((myHost, myPort))
sockobj.listen(5)
video = open('teste', 'r')
Saida=False
while 1:
connection, address = sockobj.accept()
print 'Server connected by', address
data = connection.recv(1024)
print data
if data.strip() == 'PLAY':
count = 0
while 1:
for stream in video.readlines():
count = count+1
chunk = open('chunkfile','w')
data = [count,stream]
pickle.dump(data,chunk)
chunk.close
chunktosend = open('chunkfile')
for line in chunktosend.readlines():
connection.send(line)
chunktosend.close()
else:
pass
##############################################3
#!/usr/bin/python
import SocketServer,sys,re,time,thread,threading,os,socket,random
import pickle
#print 'voce esta tentando conectar em '+ ip
sNode = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sNode.connect(('192.168.1.3', 50007))
sNode.send('PLAY')
#print sNode.recv(1024)
while 1:
x = open('testerecebido','w')
data = sNode.recv(1024)
x.write(data)
x.close()
file = open('testerecebido')
E = pickle.load(file)
print E
file.close()
#################################
Grato,
Fernando Zank Correa Evangelista
2009/4/26 Fernando Zank <fernan...@gmail.com>:
De um lado:
a = [ 1, 2, 3, 'a', 'b']
b = str(a)
conexao.send(b)
Do outro lado:
r = conexao.recv(1024)
a = eval(r)
Veja quais são os assuntos do momento no Yahoo! +Buscados
http://br.maisbuscados.yahoo.com
[As partes desta mensagem que não continham texto foram removidas]
Bem, aqui vão meus dois centavos:
Acho que o ideal seria você ter um header (como do http), constando a
ação desejada, e dados iniciais, e também o content-length dos dados.
Para enviar os bytes do objeto requerido, pode-se codificar a pickled
string com base-64, e ao receber, lê-se os `content-length` bytes da
requisição, decodifica de base64, e faz o depickling. é mais ou menos
assim que o protocolo HTTP faz (inclusive com imagens, arquivos p/
download, etc.)
Espero ter ajudado ;)
>
> >
> > Eu realmente não recomendaria receber código via rede e executá-lo... :)
> >
> > --
> > Adam Victor Nazareth Brandizzi
> > http://brandizzi.googlepages.com/
> >
>
> --
> "Somos o que repetidamente fazemos, portanto a
> excelência não é um feito é um hábito" - Aristóteles
>
--
Rodolfo Carvalho
Web Developer
rodol...@gmail.com
Francisco nesse caso que estou usando não preciso me preocupar com
segurança , é um projeto acadêmico que estou fazendo apenas para
analisar alguns dados em cima da rede depois que tiver tudo
funcionando, mas nada profissional.
A minha idéia é aprender python enquanto faço meu tcc, confesso que as
vezes é um pouco complicado pois me falta a base, mas tenho aprendido
bastante pesquisando e claro com o pessoal aqui da lista que sempre
esta disposto a ajudar e mostra a solução ou o caminho para chegar a
ela.
Grato,
Fernando Zank Correa Evangelista
2009/4/27 Adam Victor Nazareth Brandizzi <bran...@gmail.com>:
>
>
> 2009/4/27 Francisco Emilio de Paula Souza <f.em...@ymail.com>:
>
>> Tudo que é enviado por socket, vai em modo texto, assim, utilize a função
>> str() para converter as listas, tuplas, dicionários e outros tipos de dados.
>> No receptor, utilize a função eval() para voltar o dado ao tipo original.
>> É possível enviar mais de uma variável (tanto quantidade como tipo) ao
>> mesmo tempo, mas para isso se faz necessario o trabalho de união e depois
>> o de separação, por isso, para simplificar, passe um de cada vez:
>>
>> De um lado:
>> a = [ 1, 2, 3, 'a', 'b']
>> b = str(a)
>> conexao.send(b)
>>
>> Do outro lado:
>> r = conexao.recv(1024)
>> a = eval(r)
>
> Usar eval() é arriscado em geral, e nesse caso especialmente
> arriscado: abre a oportunidade para ataques em rede. Não há como
> garantir que no lugar de
>
>> a = [ 1, 2, 3, 'a', 'b']
>> b = str(a)
>> conexao.send(b)
>
> alguém faça
>
> b='os.removedirs("/")'
> conexao.send(b)
>
> Eu realmente não recomendaria receber código via rede e executá-lo... :)
>
> --
> Adam Victor Nazareth Brandizzi
> http://brandizzi.googlepages.com/
>
--
"Somos o que repetidamente fazemos, portanto a
excelência não é um feito é um hábito" - Aristóteles
Testei com o str e eval, mas no meu caso nao funcionou acho que pelo
fato do stream do video ser muito grande, vou tentar a dica do
rodolfo, vou pesquisar como fazer a codificacao em base-64, depois
posto aqui o resultado.
Grato,
Fernando Zank Correa Evangelista
2009/4/27 Rodolfo S. Carvalho <rodol...@gmail.com>:
se eu estivesse na sua situação eu faria o seguinte
- mandaria minha tupla, lista, string que é pequena se comparada ao
vídeo com os valores necessários e ainda o hash do vídeo em uma
mensagem única antes do envio do vídeo
- iniciaria o envio do vídeo checando se os pacotes estão chegando
- completado o download eu calcularia o hash do video e encontraria as
informações dele
Fiz um monte de testes agora e descobri mil coisas que nem imaginava
que existiam
base64 [1] http://docs.python.org/library/base64.html
marshal [2] http://effbot.org/librarybook/marshal.htm
xdrlib [3] http://docs.python.org/3.0/library/xdrlib.html (esse nao
funciona para enviar por socket mas eh legal para criar pacotes)
acho que o meu problema nao esta "no envio em si" mas sim no tamanho
do que estou enviando
por exemplo se eu fizer um teste sem usar o socket ele funciona
==========================================
import sys
import marshal
video = open('lost.avi', 'r')
count = 0
for stream in video.readlines():
count = count+1
data = [count,stream]
pacote = marshal.dumps(data)
saida = marshal.loads(pacote)
sys.stdout.write(saida[1])
=========================================
acho que o meu problema eh que com o socket, enviando este pacote, ele
"estora" , e entao nao tenho meu dado inteiro do outro lado.
no socket ele tem por exemplo
data = socket.recv(1024)
acho que ele ta estorando este dado.... vou ver como posso dividir o
tamanho do stream ao invez de empacotar [count, stream] vou tentar
dividir este stream com slice ou em um array... e ter tipo
[count,stream[0]]
[count,stream[1]]
[count,stream[2]]
Algo desse jeito, vou dar mais uma pesquisada, fazer mais alguns
testes e seguir apanhando e aprendendo hehehe
Grato,
Fernando Zank Correa Evangelista
2009/4/27 Danilo Faustinoni Cabello <danilo....@gmail.com>:
>
>
> 2009/4/27 Fernando Zank <fernan...@gmail.com>:
>
>> ps: desculpa a acentuacao...
>>
>> Testei com o str e eval, mas no meu caso nao funcionou acho que pelo
>> fato do stream do video ser muito grande, vou tentar a dica do
>> rodolfo, vou pesquisar como fazer a codificacao em base-64, depois
>> posto aqui o resultado.
> ps emcima é engraçado, hehehe
>
> se eu estivesse na sua situação eu faria o seguinte
>
> - mandaria minha tupla, lista, string que é pequena se comparada ao
> vídeo com os valores necessários e ainda o hash do vídeo em uma
> mensagem única antes do envio do vídeo
> - iniciaria o envio do vídeo checando se os pacotes estão chegando
> - completado o download eu calcularia o hash do video e encontraria as
> informações dele
>
--
"Somos o que repetidamente fazemos, portanto a
excelência não é um feito é um hábito" - Aristóteles
eu considerei a sua dica, infelizmente nao implementei pois nao sei
como fazer isso, por isto estou fazendo estes testes malucos aqui, se
tiver algum link com a documentacao sobre isso para que eu possa
empacotar a mensagem desta maneira agradeco.
Para mim a sua maneira eh a melhor pois pretendo criar um buffer
depois e tendo o paylod do mesmo fica melhor minha ideia inicial era
exatamente essa so nao consigo implementar.
pacote = (id, payload) # se tiver o tamanho melhor
grato,
Fernando Zank Correa Evangelista
2009/4/27 Leonardo Santagada <sant...@gmail.com>:
> Se tu quer mandar um video, faça como eu disse, mande uma mensagem de
> tamanho fixo com o tamanho do payload e depois envie o video direto
> (sem marshal/pickle/encoding em base64). E no lado de receber vai
> lendo pedaços maiores que 1024 (acho que 8192 é bom mas talvez 16384
> seja melhor ainda) mas nunca tente ler o video inteiro (algo como
> sock.read(size)) pq senão não tem streaming acontecendo :). Sockets
> não vão estourar, principalmente com videos pequenos e numa rede local.
>
> --
> Leonardo Santagada
> santagada at gmail.com
>
>
--
Se tu quer mandar um video, faça como eu disse, mande uma mensagem de
tamanho fixo com o tamanho do payload e depois envie o video direto
(sem marshal/pickle/encoding em base64). E no lado de receber vai
lendo pedaços maiores que 1024 (acho que 8192 é bom mas talvez 16384
seja melhor ainda) mas nunca tente ler o video inteiro (algo como
sock.read(size)) pq senão não tem streaming acontecendo :). Sockets
não vão estourar, principalmente com videos pequenos e numa rede local.
--
Leonardo Santagada
santagada at gmail.com
------------------------------------
Bom pessaol obrigado a todos pela ajuda, ontem de noite finalmente
consegui resolver o que precisava.
Não sei se é a melhor maneira possível, mas pelo menos funcionou rsrsrs
no lado servidor fiz algo como.(ae em baixo tá genérico o código)
########################
import struct
video = open('arquivodevideo','w')
count = 0
while 1:
stream = video.read(1000)
count = count+1
id = str(count)
id = id.rjust(24,'0')
dado = struct.pack('24s1000s',id,stream)
sock.send(dado)
#############
no cliente fiz
while 1:
dado = sock.recv(1024)
id, chunk = struct.unpack('24s1000s',dado)
id = int(id)
Bem obrigado a todos pelas ajudas e sugestões,
Fernando Zank Correa Evangelista
2009/4/27 Fernando Zank <fernan...@gmail.com>: