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