场景:Java 跟 Python 的 Socket 通信
Java 和 Python 的 Socket 通信
网络上两个程序通过一个双向通讯连接实现数据的交换,这个双向链路的一端称为一个Socket。Socket支持的协议有多种,这里主要介绍基于 TCP/IP 协议族的 Socket 编程。
首先,IP协议族决定了socket的地址类型,在通信中必须采用对应的地址。AF_INET(AF 表示 Adress Family)表示要用 ipv4 地址(32位)与端口号(16位)的组合。
然后,根据传输协议又分为:流式 Socket(SOCK_STREAM) 和数据报式 Socket(SOCK_DGRAM):
流式 SOCK_STREAM 是一种面向连接的Socket,针对于面向连接的TCP服务应用;
数据报式 SOCK_DGRAM 是一种无连接的Socket,对应于无连接的UDP服务应用;
先看一下 Java 的 Socket 通信。在 Java 环境下,Socket 编程主要就是指基于TCP/IP的网络编程,对应的 Socket API 主要是这两个类 Socket 和 ServerSocket。一个服务器端 socket 会对应多个 客户端 socket,这时就要配合多线程来实现,把 server.accept() 包在循环中,轮询监听客户端,然后每次建立连接的 socket 对象做参数建立新的线程即可。如果你只有一个客户端,那就无所谓了。
下面,通过一个最简单的例子来说明,因为文本通信是最常用的,所以这里介绍了文本通信的实现,当然也可以直接用二进制流,比如传文件。
Java 服务器 Socket
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
public class DataSocketServer {
public static void main(String[] args) {
try {
ServerSocket server = new ServerSocket(5000);
System.out.println("Server start!");
Socket socket = server.accept(); //阻塞等待, 直到一个客户端 socket过来
System.out.println("There comes a socket!");
BufferedReader in = new BufferedReader(new InputStreamReader(
socket.getInputStream())); //输入,from 客户端
PrintWriter out = new PrintWriter(socket.getOutputStream()); //输出,to 客户端
System.out.println(in.readLine()); // 打印 客户 socket 发过来的字符,按行(\n,\r,或\r\n)
out.println("Server reponse! ^_^ ");
out.flush(); // to 客户端,输出
socket.close();
server.close();
System.out.println("Server end!");
} catch (IOException e) {
e.printStackTrace();
}
}
}Java 客户端 Socketimport java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;
public class TestSocketClient {
public static void main(String[] args) {
try {
Socket socket = new Socket("127.0.0.1", 5000);
System.out.println("Client start!");
PrintWriter out = new PrintWriter(socket.getOutputStream()); // 输出,to 服务器 socket
BufferedReader in = new BufferedReader(new InputStreamReader(
socket.getInputStream())); // 输入, from 服务器 socket
out.println("Client request! :-) ");
out.flush(); // 刷缓冲输出,to 服务器
System.out.println(in.readLine()); // 打印服务器发过来的字符串
System.out.println("Client end!");
socket.close();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Python 客户端 Socket (Python 3.4)
import socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect(('localhost',5000))
print('Client start!')
sock.send(bytes('客户端:)\n',encoding='utf-8')) # str 类型 -> bytes 类型,发送,\n 千万不要少了,因为前面的 server 是按行读取的
print(str(sock.recv(1024),encoding = 'utf-8')) # bytes 类型 -> str 类型,接受
sock.close()
print('Client end!')
这里重点说明一下 Python 的 bytes 类型 和 str 类型的转换,在 Python3 中 文本和二进制数据做了更清晰的区分,文本总是 Unicode 为 str 类型,二进制则用 bytes 类型表示。清晰的划分更有利于程序的可读性和正确性。
当然,Server Socket 也可以用 Python 来写,先指定 协议和类型 socket.socket(family, type),然后绑定地址和端口, 然后进行监听,基本原理和上面是一样的。
地址:http://blog.csdn.net/thisinnocence