У меня есть сервер сокетов в Python, который будет устанавливать ssh-соединение с x-клиентами на языке C;клиент получает команды для отправки на сервер python, которые делают это через Paramiko, затем сервер отправляет результат обратно клиенту C и так далее.Проблема в том, что я получаю 2 или более реплицированных ответа (иногда и команды) из этого приложения.
И коды Python, и C получают вход / выход асинхронно, что означает, что: вход или выход вделается основной, а другая часть находится в потоке.
Код клиента C:
#include <stdio.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <string.h>
#include<unistd.h>
#include <arpa/inet.h>
#include <pthread.h>
void *receive_message(void *sock_desc)
{
int receive;
char message[2000] = {0};
while (1){
memset(message,0,sizeof(message));
receive = recv(*((int *) sock_desc),message,2000,0);
if (receive>0){
printf("%s\n", message);
}else{
printf("message error:%d\n",receive);
}
}
return NULL;
}
static int socketConnection(){
int PORT = 8081;
struct sockaddr_in address;
int sock = 0, valread;
struct sockaddr_in serv_addr;
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
printf("\n Socket creation error \n");
return -1;
}
memset(&serv_addr, '0', sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(PORT);
// Convert IPv4 and IPv6 addresses from text to binary form
if(inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr)<=0)
{
printf("\nInvalid address/ Address not supported \n");
return -1;
}
if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0)
{
printf("\nConnection Failed \n");
return -1;
}
char message[2000] = {0};
for (int i=0;i<5;i++){
strcat(message,my_argv[i]);
strcat(message,",");
}
int *new_sock;
new_sock = malloc(sizeof(int));
*new_sock = sock;
send(sock , message ,sizeof(message) , 0 );
pthread_t receive_thread;
printf("Before Thread\n");
pthread_create(&receive_thread, NULL, receive_message, (void * ) &sock);
printf("After Thread\n");
char command[2000] ={0};
while (1){
fgets(command,sizeof(command),stdin);
send(sock , command ,sizeof(command) , 0 );
memset(command,0,sizeof(command));
}
return 1;
}
int main(int argc, char const *argv[])
{
return socketConnection();;
}
server.py:
import paramiko_ssh
import socket
from threading import Thread
import time
import paramiko
class Connection:
def __init__(self, address, username, password, sock):
self.address=address
self.username=username
self.password=password
self.sock=sock
def command_loop(self):
self.client = paramiko.SSHClient()
self.client.set_missing_host_key_policy(paramiko.client.AutoAddPolicy())
self.client.connect(self.address, username=self.username, password=self.password)
self.transport = paramiko.Transport(self.address, 22)
self.transport.connect(username=self.username, password=self.password)
self.shell = self.client.invoke_shell()
cont = 0
data = ""
while True:
self.wait_answer_loop()
command = self.sock.recv(2000)
self.shell.send(command + "\n")
def wait_answer_loop(self):
data = ""
received_answer = False
while not received_answer:
if self.shell.recv_ready():
data = self.shell.recv(4096)
strdata = str(data)
strdata.replace('\r', '')
self.sock.send(strdata.split('$')[0]+'$')
received_answer = True
else:
time.sleep(1)
print('Finished loop')
def clientthread(conn):
#sends a message to the client whose user object is conn
message = conn.recv(2000)
if message:
print("message:" + message)
my_argv = message.split(",")
del(my_argv[len(my_argv)-1])
connection= paramiko_ssh.ssh("some.ip.address.to.ssh","user","password",conn)
connection.openShell()
while True:
command = conn.recv(4096)
#print("command received"+str(command))
if command.startswith(" "):
command = command[1:]
connection.sendShell(command)
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
IP_address = "localhost"
Port = 8081
server.bind((IP_address, Port))
server.listen(1000)
clients = {}
cont=0
print("waiting for new connections")
while True:
client, client_address = server.accept()
print("%s:%s has connected." % client_address)
Thread(target=clientthread, args=(client,)).start()
#conn.close()
#server.close()
paramiko_ssh.py
import threading, paramiko,socket
class ssh:
shell = None
client = None
transport = None
def __init__(self, address, username, password,socket):
print("Connecting to server on ip", str(address) + ".")
self.client = paramiko.client.SSHClient()
self.client.set_missing_host_key_policy(paramiko.client.AutoAddPolicy())
self.socket=socket
self.client.connect(address, username=username, password=password, look_for_keys=False)
self.transport = paramiko.Transport((address, 22))
self.transport.connect(username=username, password=password)
thread = threading.Thread(target=self.process)
thread.daemon = True
thread.start()
def closeConnection(self):
if(self.client != None):
self.client.close()
self.transport.close()
def openShell(self):
self.shell = self.client.invoke_shell()
def sendShell(self, command):
if(self.shell):
self.shell.send(command + "\n")
else:
print("Shell not opened.")
def process(self):
global connection
strdata=''
while True:
# Print data when available
if self.shell != None and self.shell.recv_ready():
alldata = self.shell.recv(4096)
while self.shell.recv_ready():
alldata += self.shell.recv(4096)
strdata = str(alldata)
strdata.replace('\r', '')
print(strdata +"")
self.socket.send(strdata +"")
Я предполагаю, что ясделал что-то не так в управлении сокетами при входе / выходе, но я не вижу, в чем проблема.