Python服务器与多种客户端(Python/Java/Android)之间的通信

概述:

  我们不会一直满足于客户端程序的开发,因为太过受限了。为了打破这样的受限,你需要做的就是去编写服务器端代码。以及如何在服务器与客户端之间的通信。以下将对此以Python为服务器,并分别以Python、Java、Android为客户端作一个简单的介绍。


服务器端:

test_tcp_server.py

#!/usr/bin/env python

from socket import *
from time import ctime

HOST = ''
PORT = 21567
BUFSIZ = 1024
ADDR = (HOST, PORT)

tcpSerSock = socket(AF_INET, SOCK_STREAM)
tcpSerSock.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
tcpSerSock.bind(ADDR)
tcpSerSock.listen(5)

while True:
    print 'waiting for connection...'
    tcpCliSock, addr = tcpSerSock.accept()
    print '...connected from:', addr
    
    while True:
        data = tcpCliSock.recv(BUFSIZ)
        if not data:
            break
        tcpCliSock.send('get your data:%s\n[%s]' % (data, ctime()))
    
        tcpCliSock.close
        
tcpSerSock.close
对于上面的代码,有一点需要我们来注意一下。tcpSerSock.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)。当然如果你高兴,可以不加上这一句,不过不加这一句的后果就是上面的端口不能再复用。

客户端:

1.python

#!/usr/bin/env python

from socket import *

HOST = 'input your host ip'
PORT = 21567
BUFSIZ = 1024
ADDR = (HOST, PORT)

tcpCliSock = socket(AF_INET, SOCK_STREAM)
tcpCliSock.connect(ADDR)

while True:
    data = raw_input('> ')
    if not data:
        break
    tcpCliSock.send(data)
    
    recv_data = tcpCliSock.recv(BUFSIZ)
    if not recv_data:
        break
    print recv_data

tcpCliSock.close()
技术分享

2.Java

public static void main(String[] args) throws IOException {
        
        Socket socket = new Socket(HOST, PORT);
        OutputStream outputStream = socket.getOutputStream();
        outputStream.write(("Hello server with java").getBytes());
        outputStream.flush();
        System.out.println(socket);
        
        InputStream is = socket.getInputStream();
        byte[] bytes = new byte[1024];
        int n = is.read(bytes);
        System.out.println(new String(bytes, 0, n));
        
        is.close();
        socket.close();
    }

运行效果图:

技术分享

3.Android

public class TCPClientActivity extends Activity {
    
    private int getLayoutResID() {
        return R.layout.activity_tcp_client;
    }
    
    private final int HANDLER_MSG_TELL_RECV = 0x124;
    
    private EditText mHostEditText = null;
    private EditText mPortEditText = null;
    private EditText mContentEditText = null;
    
    private Button mSubmitButton = null;
    private Button mCancelButton = null;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(getLayoutResID());
        
        initEvent();
    }
    
    private void initEvent() {
        initViews();
        
        setViews();
    }
    
    private void initViews() {
        mHostEditText = (EditText) findViewById(R.id.client_method_editText);
        mPortEditText = (EditText) findViewById(R.id.client_mode_editText);
        mContentEditText = (EditText) findViewById(R.id.client_content_editText);
        
        mSubmitButton = (Button) findViewById(R.id.client_submit_button);
        mCancelButton = (Button) findViewById(R.id.client_cancel_button);
    }
    
    private void setViews() {
        mSubmitButton.setOnClickListener(new OnClickListener() {
            
            @Override
            public void onClick(View arg0) {
                String host = mHostEditText.getText().toString();
                String port = mPortEditText.getText().toString();
                String content = mContentEditText.getText().toString();
                
                Toast.makeText(TCPClientActivity.this, host + ", " + port + ", " + content, 0).show();
                startNetThread(host, Integer.parseInt(port), content);
            }
        });
        
        mCancelButton.setOnClickListener(new OnClickListener() {
            
            @Override
            public void onClick(View arg0) {
                setEmptyEdittext();
            }
        });
    }
    
    private void startNetThread(final String host, final int port, final String data) {
        Thread thread = new Thread() {
            @Override
            public void run() {
                try {
                    Socket socket = new Socket(host, port);
                    OutputStream outputStream = socket.getOutputStream();
                    outputStream.write((data).getBytes());
                    outputStream.flush();
                    System.out.println(socket);
                    
                    InputStream is = socket.getInputStream();
                    byte[] bytes = new byte[1024];
                    int n = is.read(bytes);
                    System.out.println(new String(bytes, 0, n));
                    
                    Message msg = handler.obtainMessage(HANDLER_MSG_TELL_RECV, new String(bytes, 0, n));
                    msg.sendToTarget();
                    
                    is.close();
                    socket.close();
                } catch (Exception e) {
                }
            }
        };
        
        thread.start();
    }
    
    Handler handler = new Handler() {
        public void handleMessage(Message msg) {
            AlertDialog.Builder builder = new AlertDialog.Builder(TCPClientActivity.this);
            builder.setMessage("来自服务器的数据:" + (String)msg.obj);
            builder.create().show();
        };
    };
    
    private void setEmptyEdittext() {
        mHostEditText.setText("");
        mPortEditText.setText("");
        mContentEditText.setText("");
    }
}
运行效果图:

技术分享

备注:对于上面的客户端程序,我想是没有什么问题的。不过如果你只是原原本本按照上面的流程来走,可能会运行不了。因为你Linux中的防火墙受限,在实验中我们通常选择关闭防火墙:

# /etc/init.d/iptables stop

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。