Сервер и клиент на Python и C

Я написал простой клиентский код на Python и пытаюсь подключиться к простому эхо-серверу, написанному на C.

Я знаю, что это не должно иметь значения, но по какой-то причине мне удалось подключиться к серверу, написанному на python, но я не могу подключиться к серверу C.

Вот код клиента:

import socket
import sys
import time

HOST = 'localhost'
PORT = 11000
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST, PORT))
msg = raw_input()
s.send(msg)
data = s.recv(len(msg))
s.close()
print 'Received: ', data

А вот код C эхо-сервера:

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <netinet/in.h>
#include <string.h>
#include <netdb.h>

#ifndef AF_INET
#define AF_INET 2
#endif

#ifndef SOCK_DGRAM
#define SOCK_DGRAM 2
#endif

#ifndef INADDR_ANY
#define INADDR_ANY 0
#endif

#ifndef IP_DONTFRAG
#define IP_DONTFRAG     67
#endif

#define BUFFER_SIZE 1024

#define ECHO_PORT_UDP 10000
#define ECHO_PORT_TCP 11000

int main(int argc, char *argv[]) {
int echo_socket = 0;
int echo_socket_child = 0; // for TCP
struct sockaddr_in server;
struct sockaddr_in client;
struct hostent *hostp; // client host info
struct sockaddr_in clientaddr; // client addr
char *hostaddrp; // dotted decimal host addr string
char buffer[BUFFER_SIZE];
unsigned int clientlen = 0;
unsigned int serverlen = 0;
int received = 0;
int port = 0;
char *endptr;
int optval = 1;
int msg_byte_size = 0;// Parameters check
if (argc == 2) {
port = strtol(argv[1], &endptr, 0);
if ((*endptr) || ((port != ECHO_PORT_UDP) && (port != ECHO_PORT_TCP)))  {
printf("EchoServer: Invalid port number.\n Use port %d for UDP, port %d for TCP.\n", ECHO_PORT_UDP, ECHO_PORT_TCP);
return -1;
}
else {
if (port == ECHO_PORT_UDP) {
printf("EchoServer: Running UDP on port %d.\n", port);
}
if (port == ECHO_PORT_TCP) {
printf("EchoServer: Running TCP on port %d.\n", port);
}
}
}
else {
printf("EchoServer: Invalid arguments.\n");
return -1;
}// Opening UDP socket
if (port == ECHO_PORT_UDP) {
if ((echo_socket = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
printf("EchoServer: Failed opening socket");
return -1;
}

}
if (port == ECHO_PORT_TCP) {
if ((echo_socket = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
printf("EchoServer: Failed opening socket");
return -1;
}

// setsockopt: Handy debugging trick that lets  us rerun the server immediately after we kill it; otherwise we have to wait about 20 secs.
// Eliminates "ERROR on binding: Address already in use" error.
setsockopt(echo_socket, SOL_SOCKET, SO_REUSEADDR,(const void *)&optval , sizeof(int));

}

// Construct the server sockaddr_in structure
memset(&server, 0, sizeof(server));             /* Clear struct */
server.sin_family = AF_INET;                    /* Internet/IP */
server.sin_addr.s_addr = htonl(INADDR_ANY);     /* Any IP address */
server.sin_port = htons(atol(argv[1]));         /* server port */

// Bind the socket
serverlen = sizeof(server);
if (bind(echo_socket, (struct sockaddr *) &server, serverlen) < 0) {
printf("EchoServer: Failed binding socket");
return -1;
}// Wait for a datagram until cancelled
if (port == ECHO_PORT_UDP) {
while (1) {
/* Receive a message from the client */
clientlen = sizeof(client);
if ((received = recvfrom(echo_socket, buffer, BUFFER_SIZE, 0, (struct sockaddr *)&client, &clientlen)) < 0) {

printf("EchoServer: Failed receiving datagram");
return -1;
}
printf("Client datagram received from: %s\n", inet_ntoa(client.sin_addr));
/* Send the message back to client */
if (sendto(echo_socket, buffer, received, 0, (struct sockaddr *) &client, sizeof(client)) != received) {
printf("Mismatch in number of echoed bytes");
return -1;
}
}
}

// Wait for a connection until cancelled
if (port == ECHO_PORT_TCP) {
while (1) {
echo_socket_child = accept(echo_socket, (struct sockaddr *) &client, &clientlen);
if (echo_socket_child < 0) {
printf("ERROR on accept");
break;
}

// gethostbyaddr: determine who sent the message
hostp = gethostbyaddr((const char *)&clientaddr.sin_addr.s_addr, sizeof(clientaddr.sin_addr.s_addr), AF_INET);
if (hostp == NULL) {
printf("ERROR on gethostbyaddr");
break;
}
hostaddrp = inet_ntoa(clientaddr.sin_addr);
if (hostaddrp == NULL) {
printf("ERROR on inet_ntoa\n");
break;
}
printf("server established connection with %s \n", hostaddrp);

// read: read input string from the client
bzero(buffer, BUFFER_SIZE);
msg_byte_size = read(echo_socket_child, buffer, BUFFER_SIZE);
if (msg_byte_size < 0) {
printf("ERROR reading from socket");
break;
}
printf("server received %d bytes: %s", msg_byte_size, buffer);

// write: echo the input string back to the client
msg_byte_size = write(echo_socket_child, buffer, strlen(buffer));
if (msg_byte_size < 0) {
printf("ERROR writing to socket");
break;
}
} // endof while(1)
close(echo_socket_child);
return -1;
}
return 0;

}

Есть идеи, почему я не могу подключиться к серверу?

редактировать:
это ошибка, которую я получаю:

Traceback (most recent call last):
File "s.py", line 8, in <module>
s.connect((HOST, PORT))
File "C:\Python27\lib\socket.py", line 224, in meth
return getattr(self._sock,name)(*args)
socket.error: [Errno 10061]

0

Решение

(1) Добавить listen позвоните в раздел TCP кода.

(2) Вы должны сказать accept какова длина передаваемого вами sockaddr, и он, в свою очередь, сообщит вам длину адреса возвращенного клиента. Вы передавали его как 0 длины, поэтому, естественно, он не передал адрес клиента, который впоследствии делает ваш gethostbyaddr Ошибка с неизвестным адресом.

(3) Если вы не закроете клиентский сокет в цикле, он просто останется открытым (и утечка файлового дескриптора) на время жизни сервера. В конце концов у вас закончатся FD. Это не влияет на ваш клиент, который просто закрывается после получения одного сообщения, но любой клиент, который пишет более одного сообщения, никогда не получит его от сервера и никогда не получит eof от сервера.

if (port == ECHO_PORT_TCP)
{
if (listen(echo_socket, ECHO_PORT_TCP) == -1)
{
perror("listen");
exit(1);
}

while (1)
{
clientlen = sizeof(client);

echo_socket_child = accept(echo_socket, (struct sockaddr *) &client, &clientlen);

if (echo_socket_child < 0)
{
perror("accept");
break;
}

// gethostbyaddr: determine who sent the message
hostp = gethostbyaddr((const char *) &client.sin_addr.s_addr, sizeof(client.sin_addr.s_addr), AF_INET);

if (hostp == NULL)
{   herror("byaddr");
break;
}

hostaddrp = inet_ntoa(client.sin_addr);

if (hostaddrp == NULL)
{
printf("ERROR on inet_ntoa\n");
break;
}

printf("server established connection with %s (%s)\n", hostp->h_name, hostaddrp);

bzero(buffer, BUFFER_SIZE);
msg_byte_size = read(echo_socket_child, buffer, BUFFER_SIZE);

if (msg_byte_size < 0)
{
printf("ERROR reading from socket");
break;
}

printf("server received %d bytes: %s", msg_byte_size, buffer);

msg_byte_size = write(echo_socket_child, buffer, strlen(buffer));

if (msg_byte_size < 0)
{
printf("ERROR writing to socket");
break;
}

close(echo_socket_child);

} // endof while(1)

return -1;
}
0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]