首页 > 代码库 > 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 客户端 Socket
import 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