一、socket
所谓套接字(Socket),就是对网络中不同主机上的应用进程之间进行双向通信的端点的抽象。一个套接字就是网络上进程通信的一端,提供了应用层进程利用网络协议交换数据的机制。从所处的地位来讲,套接字上联应用进程,下联网络协议栈,是应用程序通过网络协议进行通信的接口,是应用程序与网络协议根进行交互的接口 [1] 。
个人理解socket的好处:便于选择传输层的协议,另外sokect双向工便于做实时传输,长连接。
二、环境
pycharm +idea
三、实现
(1)socket实现 udp编程
Internet 协议集支持一个无连接的传输协议,该协议称为用户数据报协议(UDP,User Datagram Protocol)。UDP 为应用程序提供了一种无需建立连接就可以发送封装的 IP 数据包的方法。RFC 768 描述了 UDP。Internet 的传输层有两个主要协议,互为补充。
使用udp的一般为语言通话,实时游戏对数据准确性不那么高的。作为一个程序员应该根据需要去选择用udp还是TCP
udp连接由于是无连接的,因此就直接进行扔数据传输即可,代码如下。
python:
Server端
from socket import *
# tuple绑定本地端口
serverPort = ('', 1200)
# 定义serverSocket SOCK_DGRAM UDP
# SOCK_DGRAM UDP
serverSocket = socket(AF_INET, SOCK_DGRAM)
# 将socket绑定到此端口
serverSocket.bind(serverPort)
print("The Server is ready to receive")
i = 1
# 循环等待并处理返回
while i == 1:
message, clientAddress = serverSocket.recvfrom(2048)
modifiedMessage = message.upper()
serverSocket.sendto(modifiedMessage, clientAddress)
client端
# 引入socket的模板
from socket import *
# 定义主机名(IP,域名=>DNS解析为IP)
from pip._vendor.distlib.compat import raw_input
serverName = 'localhost'
# 定义服务器端口号
serverPort = 1200
# 创建用户socket AF_INET IPv4,SOCK_DGRAM UDP
clientSocket = socket(AF_INET, SOCK_DGRAM)
# 定义输入的信息
message = raw_input("请输入发送的数据:")
# 发送数据
clientSocket.sendto(bytes(message, 'utf8'), (serverName, serverPort))
modifiedMessage, serverAddress = clientSocket.recvfrom(2048)
print(modifiedMessage, serverAddress)
clientSocket.close()
测试效果:
用wireshark进行测试一下,捕获到此端口发数据,有兴趣可以点开看下具体数据。
(2)TCP形式
tcp和udp类似,主要区别在发送数据之前需要进行connect连接以及socket创建的TCP和UDP选择,也就是三次握手这个动作,确定连接再进行发送数据。所以时间会比udp长,可以进行测试一下。
client
from socket import *
from pip._vendor.distlib.compat import raw_input
serverName = 'localhost'
serverPort = 1201
# 创建TCP 套接字 SOCK_STREAM
clientSocket = socket(AF_INET, SOCK_STREAM)
# 进行连接 (UDP无需此步)
clientSocket.connect((serverName, serverPort)) #可能需要tuple
msg = raw_input("请输入发送信息")
# 直接发送信息即可,无需指定地址
clientSocket.send(bytes(msg, 'utf8'))
# 1024指定长度
receiveMsg = clientSocket.recvfrom(1024)
print(receiveMsg)
clientSocket.close()
server
from socket import *
from pip._vendor.distlib.compat import raw_input
serverName = 'localhost'
serverPort = 1201
# 创建TCP 套接字 SOCK_STREAM
clientSocket = socket(AF_INET, SOCK_STREAM)
# 进行连接 (UDP无需此步)
clientSocket.connect((serverName, serverPort)) #可能需要tuple
msg = raw_input("请输入发送信息")
# 直接发送信息即可,无需指定地址
clientSocket.send(bytes(msg, 'utf8'))
# 1024指定长度
receiveMsg = clientSocket.recvfrom(1024)
print(receiveMsg)
clientSocket.close()
JAVA版
server
package socket;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketAddress;
public class TCPServer {
public static void main(String[]args) throws IOException {
ServerSocket serverSocket = new ServerSocket(1202);
// 连接超时
while(true){
serverSocket.setSoTimeout(10000);
Socket server = serverSocket.accept();
System.out.println("等待远程连接...");
DataInputStream in = new DataInputStream(server.getInputStream());
String str = in.readUTF();
System.out.println("receive:"+str);
DataOutputStream outputStream = new DataOutputStream(server.getOutputStream());
outputStream.writeUTF("server has received "+str);
//若此处再使用in.readUTF(),将会出错
System.out.println("server has send!");
server.close();
}
}
}
client
package socket;
import java.io.*;
import java.net.Socket;
import java.net.SocketAddress;
public class TCPClient {
public static void main(String[]args) throws IOException, InterruptedException {
// 建立socket对象,host和port
Socket socket = new Socket("localhost",1202);
OutputStream clientOut = socket.getOutputStream();
DataOutputStream out = new DataOutputStream(clientOut);
// writeUTF 直接字符串写入
out.writeUTF("hello"+socket.getRemoteSocketAddress());
Thread.sleep(3000);
InputStream receiveMsg = socket.getInputStream();
DataInputStream in = new DataInputStream(receiveMsg);
System.out.println("服务器响应:"+in.readUTF());
socket.close();
}
}