服务器和客户端在Python和C [英] Server and client in Python and C

查看:121
本文介绍了服务器和客户端在Python和C的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经写在python一个简单的客户端code,我试图连接到C语言编写的一个简单的echo服务器。

我知道这不应该的问题,但由于某些原因,我没有管理连接到Python编写的一台服务器,但我无法连接到C服务器。

下面是客户端的code:

 进口插座
进口SYS
进口时间HOST ='localhost'的
PORT = 11000
S = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.connect((主机,端口))
味精的raw_input =()
s.send(MSG)
数据= s.recv(LEN(MSG))
S.CLOSE()
打印收到:数据

和这里的回声服务器的C code:

 的#include<&stdio.h中GT;
#包括LT&;&stdlib.h中GT;
#包括LT&; SYS / types.h中>
#包括LT&; SYS / socket.h中>
#包括LT&; ARPA / inet.h>
#包括LT&;&unistd.h中GT;
#包括LT&; netinet / in.h中>
#包括LT&;&string.h中GT;
#包括LT&;&netdb.h中GT;的#ifndef AF_INET
#定义AF_INET 2
#万一SOCK_DGRAM的#ifndef
#定义SOCK_DGRAM 2
#万一的#ifndef INADDR_ANY
的#define INADDR_ANY 0
#万一的#ifndef IP_DONTFRAG
#定义IP_DONTFRAG 67
#万一的#define BUFFER_SIZE 1024#定义ECHO_PORT_UDP 10000
#定义ECHO_PORT_TCP 11000INT主(INT ARGC,CHAR *的argv []){
    INT echo_socket = 0;
    INT echo_socket_child = 0; //为TCP
    结构SOCKADDR_IN服务器;
    结构sockaddr_in的客户端;
    结构hostent * hostp; //客户端主机信息
    结构SOCKADDR_IN clientaddr; //客户端地址
    字符* hostaddrp; //点​​分十进制地址的主机字符串
    字符缓冲区[BUFFER_SIZE];
    unsigned int类型clientlen = 0;
    unsigned int类型serverlen = 0;
    INT接收= 0;
    INT端口= 0;
    字符* endptr;
    INT optval的= 1;
    INT msg_byte_size = 0;
//参数检查
    如果(的argc == 2){
        端口= strtol将(argv的[1],&放大器; endptr,0);
        如果((* endptr)||((端口= ECHO_PORT_UDP)及!&放大器;!(端口= ECHO_PORT_TCP))){
        的printf(EchoServer的:端口号无效\\ n使用端口%d的支持UDP,TCP端口%d个\\ n,ECHO_PORT_UDP,ECHO_PORT_TCP);
            返回-1;
        }
        其他{
            如果(端口== ECHO_PORT_UDP){
                的printf(EchoServer的:端口%d上运行UDP \\ n,口);
            }
            如果(端口== ECHO_PORT_TCP){
                的printf(EchoServer的:运行在端口%d的TCP \\ n,口);
            }
        }
    }
    其他{
        的printf(EchoServer的:无效的参数\\ n);
        返回-1;
    }
//打开UDP套接字
    如果(端口== ECHO_PORT_UDP){
        如果((echo_socket =插座(AF_INET,SOCK_DGRAM,0))℃,){
            的printf(EchoServer的:无法打开插座);
            返回-1;
        }    }
    如果(端口== ECHO_PORT_TCP){
        如果((echo_socket =插座(AF_INET,SOCK_STREAM,0))小于0){
            的printf(EchoServer的:无法打开插座);
            返回-1;
        }        // setsockopt的:便捷的调试技巧,可以让我们重新运行后,我们立即杀死它的服务器;否则,我们不得不等待约20秒。
        //消除错误绑定:地址已在使用的错误。
        setsockopt的(echo_socket,SOL_SOCKET,SO_REUSEADDR,(常量无效*)及optval的,的sizeof(INT));    }//构建服务器SOCKADDR_IN结构
    memset的(安培;服务器,0,sizeof的(服务器)); / *清除结构* /
    server.sin_family = AF_INET; / *互联网/ IP * /
    server.sin_addr.s_addr = htonl(INADDR_ANY); / *任何IP地址* /
    server.sin_port = htons(蒂(的argv [1])); /* 服务器端口 *///绑定插座
    serverlen = sizeof的(服务器);
    如果(绑定(echo_socket,(结构sockaddr *)及服务器,serverlen)小于0){
        的printf(EchoServer的:无法绑定套接字);
        返回-1;
}
//等待一个数据包,直到取消
如果(端口== ECHO_PORT_UDP){
    而(1){
        / *接收来自客户端的消息* /
        clientlen = sizeof的(客户端);
        如果((接收= recvfrom的(echo_socket,缓冲器,BUFFER_SIZE,0,(结构sockaddr *)及客户端,与放大器; clientlen))小于0){            的printf(EchoServer的:无法接收数据报);
            返回-1;
        }
        的printf(客户端的数据报收到:%S \\ n,INET_NTOA(client.sin_addr));
        / *将消息发送回客户端* /
        如果(SENDTO(echo_socket,缓冲器,接收,0,(结构sockaddr *)及!客户端的sizeof(客户端))=接收){
            的printf(不匹配呼应的字节数);
            返回-1;
        }
    }
}//等待连接直到取消
如果(端口== ECHO_PORT_TCP){
    而(1){
        echo_socket_child =接受(echo_socket,(结构sockaddr *)及客户端,和放大器; clientlen);
        如果(echo_socket_child℃,){
            的printf(ERROR在接受);
            打破;
        }        // gethostbyaddr:确定谁发送消息
        hostp = gethostbyaddr((为const char *)及clientaddr.sin_addr.s_addr,sizeof的(clientaddr.sin_addr.s_addr),AF_INET);
        如果(hostp == NULL){
            的printf(关于gethostbyaddr ERROR);
            打破;
        }
        hostaddrp = INET_NTOA(clientaddr.sin_addr);
        如果(hostaddrp == NULL){
            的printf(关于INET_NTOA \\ n错误);
            打破;
        }
        的printf(服务器建立与%s \\ n连接,hostaddrp);        //读取:从客户端读取输入字符串
        bzero(缓冲,BUFFER_SIZE);
        msg_byte_size =读(echo_socket_child,缓冲,BUFFER_SIZE);
        如果(msg_byte_size℃,){
            的printf(ERROR从套接字读取);
            打破;
        }
        的printf(服务器收到%d字节:%S,msg_byte_size,缓冲区);        //写:回声输入字符串返回给客户端
        msg_byte_size =写入(echo_socket_child,缓冲液,strlen的(缓冲液));
        如果(msg_byte_size℃,){
            的printf(写入插座);
            打破;
        }
    } // endof而(1)
    关闭(echo_socket_child);
    返回-1;
}
返回0;

}

为什么我不能任何想法连接到服务器?

编辑:
这是我收到的错误:

 回溯(最后最近一次调用):
  文件s.py,8号线,上述<&模块GT;
    s.connect((主机,端口))
  文件C:\\ Python27 \\ lib目录\\ socket.py,线路224,在甲基
    返回GETATTR(self._sock,名字)(*参数)
socket.error:[错误10061]


解决方案

(1)添加打电话到code的TCP部分。

(2)你必须告诉接受要传递什么的sockaddr的长度是,它会回报告诉你客户端的地址的长度它返回。你是把它当作0长度所以自然也没有传回客户端地址,随后使你的 gethostbyaddr 失败,未知的地址。

(3)如果你不只是保持打开状态(和泄漏文件描述符)服务器的生命期限内环路关闭客户端套接字。最终你会用完文件描述符的。它不会影响你的客户收到一个MSG,但任何客户端谁写多个消息将永远不会有它由服务器接收,绝不会从服务器接收到一个EOF后刚刚关闭。

 如果(端口== ECHO_PORT_TCP)
{
    如果(听(echo_socket,ECHO_PORT_TCP)== -1)
    {
        PERROR(听);
        出口(1);
    }    而(1)
    {
        clientlen = sizeof的(客户端);        echo_socket_child =接受(echo_socket,(结构sockaddr *)及客户端,和放大器; clientlen);        如果(echo_socket_child℃,)
        {
              PERROR(接受);
              打破;
        }        // gethostbyaddr:确定谁发送消息
        hostp = gethostbyaddr((为const char *)及client.sin_addr.s_addr,sizeof的(client.sin_addr.s_addr),AF_INET);        如果(hostp == NULL)
        {herror(都是标准);
            打破;
        }        hostaddrp = INET_NTOA(client.sin_addr);        如果(hostaddrp == NULL)
        {
            的printf(关于INET_NTOA \\ n错误);
            打破;
        }        的printf(服务器建立与%s(%s的连接)\\ n,hostp-> h_name,hostaddrp);        bzero(缓冲,BUFFER_SIZE);
        msg_byte_size =读(echo_socket_child,缓冲,BUFFER_SIZE);        如果(msg_byte_size℃,)
        {
            的printf(ERROR从套接字读取);
            打破;
        }        的printf(服务器收到%d字节:%S,msg_byte_size,缓冲区);        msg_byte_size =写入(echo_socket_child,缓冲液,strlen的(缓冲液));        如果(msg_byte_size℃,)
        {
            的printf(写入插座);
            打破;
        }        关闭(echo_socket_child);    } // endof而(1)    返回-1;
}

I've wrote a simple client code in python, and I'm trying to connect to a simple echo server written in C.

I know it shouldn't matter, but for some reason I did manage to connect to a server written in python, but I cannot connect to the C server.

Here's the code of the client:

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

And here's the C code of the echo server:

#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;

}

Any ideas why I fail to connect to the server?

edit: this is the error I receive:

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]

解决方案

(1) Add a listen call to the TCP section of the code.

(2) You have to tell accept what the length of the sockaddr you are passing it is and it will in return tell you the length of the address of the client it returned. You were passing it as 0 length so naturally it didn't pass back a client address which subsequently makes your gethostbyaddr fail with unknown address.

(3) If you don't close the client socket within the loop it just remains open (and leaks a file descriptor) for the duration of the server's life. Eventually you will run out of FDs. It doesn't effect your client which just closes after the receipt of one msg but any client who writes more than one message will never have it received by the server and will never receive an eof from the server.

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;
}

这篇关于服务器和客户端在Python和C的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆