概述:
我们不会一直满足于客户端程序的开发,因为太过受限了。为了打破这样的受限,你需要做的就是去编写服务器端代码。以及如何在服务器与客户端之间的通信。以下将对此以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 [%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