Socket编程

Socket(套接字)是计算机网络编程中用于实现网络通信的一种机制。它提供了一种编程接口,允许应用程序通过网络进行数据传输,实现不同主机之间的通信。

Socket可以看作是一种抽象的概念,用于描述网络通信的端点。它包含了通信所需的各种参数和状态信息,以便应用程序能够通过它进行数据的发送和接收。

Socket的主要特点

通信协议:Socket可以基于不同的通信协议进行数据传输,例如TCP/IP、UDP等。
通信模型:Socket可以支持不同的通信模型,如面向连接的流式Socket(如TCP)和无连接的数据报式Socket(如UDP)。
客户端-服务器模型:Socket通常用于实现客户端-服务器模型,其中客户端应用程序通过Socket与服务器进行通信。
端口号:Socket通过端口号来标识应用程序的通信端口,以便不同的应用程序能够同时在同一台主机上进行网络通信。
API接口:Socket提供了一组API接口,供应用程序进行Socket编程,包括建立连接、发送数据、接收数据、关闭连接等操作。

Socket编程可以在不同的编程语言中进行,如C、C++、Java、Python等,通过调用相应的Socket API来实现网络通信功能。

主要步骤

1、创建Socket:使用Socket API创建一个Socket对象,指定协议类型和通信模式。
2、绑定端口:将Socket绑定到本地的IP地址和端口号上。
3、监听连接请求(仅服务器端):对于服务器端,调用Socket API监听来自客户端的连接请求。
4、建立连接(仅客户端):对于客户端,调用Socket API与服务器端建立连接。
5、数据传输:通过Socket发送和接收数据。
6、关闭连接:在通信结束后,关闭Socket连接。

Socket编程可以用于各种网络应用,如Web服务器、邮件服务器、聊天应用、游戏等。它为应用程序提供了灵活、可靠和高效的网络通信方式。

python socket

服务端

#!/usr/bin/python3
# 文件名:server.py

# 导入 socket、sys 模块
import socket
import sys

# 创建 socket 对象
serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 

# 获取本地主机名
host = '127.0.0.1' #socket.gethostname()

port = 9998

# 绑定端口号
serversocket.bind((host, port))

# 设置最大连接数,超过后排队
serversocket.listen(5)
print(f'服务器已启动,等待连接>>>')

# 建立客户端连接
clientsocket,addr = serversocket.accept()
print(f"连接地址: {str(addr)}")

while True:
	print(f'等待数据>>>>')
	data = clientsocket.recv(1024)
	#判断客户端链接状态
	if data:
		print(f"{str(data.decode('utf-8'))}")
	else:
		break
	msg='欢迎访问>>>>'+ str(data.decode('utf-8')) + "\r\n"
	clientsocket.send(msg.encode('utf-8'))

clientsocket.close()


# 启动命令
python3 server.py

客户端

#!/usr/bin/python3
# 文件名:client.py

# 导入 socket、sys 模块
import socket
import sys

# 创建 socket 对象
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 

# 获取本地主机名
host = '127.0.0.1' #socket.gethostname() 
print(f'{host}')

# 设置端口号
port = 9998

# 连接服务,指定主机和端口
s.connect((host, port))
print("链接成功")

while True:

	data = input("请输入发送给服务器的数据:")
	print(data)
	if data == '0':
		#断开连接
		s.close()
		print("已断开链接……")
		break
	#发送数据
	s.send(data.encode("utf-8"))
	print("发送成功!")

	# 接收服务器响应小于 1024 字节的数据
	msg = s.recv(1024)
	print (msg.decode('utf-8'))

s.close()

# 启动命令
python3 client.py

java

服务端

// 文件名 GreetingServer.java
 
import java.net.*;
import java.io.*;
 
public class GreetingServer extends Thread
{
   private ServerSocket serverSocket;
   
   public GreetingServer(int port) throws IOException
   {
      serverSocket = new ServerSocket(port);
      //serverSocket.setSoTimeout(10000);
   }
 
   public void run()
   {
      while(true)
      {
         try
         {
            System.out.println("等待远程连接,端口号为:" + serverSocket.getLocalPort() + "...");
            Socket server = serverSocket.accept();
            System.out.println("远程主机地址:" + server.getRemoteSocketAddress());
            DataInputStream in = new DataInputStream(server.getInputStream());
            System.out.println(in.readUTF());
            DataOutputStream out = new DataOutputStream(server.getOutputStream());
            out.writeUTF("谢谢连接我:" + server.getLocalSocketAddress() + "\nGoodbye!");
            server.close();
         }catch(SocketTimeoutException s)
         {
            System.out.println("Socket timed out!");
            break;
         }catch(IOException e)
         {
            e.printStackTrace();
            break;
         }
      }
   }
   public static void main(String [] args)
   {
      int port = Integer.parseInt(args[0]);
      try
      {
         Thread t = new GreetingServer(port);
         t.run();
      }catch(IOException e)
      {
         e.printStackTrace();
      }
   }
}

//启动命令
java GreetingServer.java 6666

客户端

// 文件名 GreetingClient.java
 
import java.net.*;
import java.io.*;
 
public class GreetingClient
{
   public static void main(String [] args)
   {
      String serverName = args[0];
      int port = Integer.parseInt(args[1]);
      try
      {
         System.out.println("连接到主机:" + serverName + " ,端口号:" + port);
         Socket client = new Socket(serverName, port);
         System.out.println("远程主机地址:" + client.getRemoteSocketAddress());
         OutputStream outToServer = client.getOutputStream();
         DataOutputStream out = new DataOutputStream(outToServer);
 
         out.writeUTF("Hello from " + client.getLocalSocketAddress());
         InputStream inFromServer = client.getInputStream();
         DataInputStream in = new DataInputStream(inFromServer);
         System.out.println("服务器响应: " + in.readUTF());
         client.close();
      }catch(IOException e)
      {
         e.printStackTrace();
      }
   }
}

//启动命令
java GreetingClient.java localhost 6666

php

服务端

<?php
//文件名 server.php
set_time_limit(0);
 
$ip = '127.0.0.1';
$port = '65533';
// socket_create(): 初始化一个socket资源
// socket_strerror(): 根据错误号获取错误消息
// socket_last_error(): 返回上一次错误的错误号
if(($sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP)) === FALSE)
{
	echo '初始化socket失败: ' . socket_strerror(socket_last_error($sock));
	die;
}
 
// socket_bind(): 将socket资源绑定到指定地址
if(!socket_bind($sock, $ip, $port))
{
	echo '绑定端口失败: ' . socket_strerror(socket_last_error($sock));
	die;
}
 
// socket_listen(): 监听socket的连接请求
if(!socket_listen($sock))
{
	echo '监听端口: ' . socket_strerror(socket_last_error($sock));
	die;
}
 
// 建立死循环,循环接收客户端的连接请求,持续向连接上的客户端推送消息
while(1)
{
	// socket_accept(): 接受来自客户端的连接, 返回一个新socket资源用于通讯. 如果接收到多个连接, 只会使用第一个连接. 没有连接时, 该函数保持堵塞状态, 直到有新的连接. 如果使用socket_set_blocking() or socket_set_nonblock()将socket设置为非堵塞状态, 没有连接时该函数返回FALSE
	;
	if(($client = socket_accept($sock)) === FALSE)
	{
		echo '接收连接失败: ' . socket_strerror(socket_last_error($sock));
		die;
	}
	$data = '服务端消息: ' . date('Y-m-d H:i:s', time());
	socket_write($client, $data);
	socket_close($client);
}
 
socket_close($sock);

//启动命令
php server.php

客户端

<?php
// 文件名 client.php
// 服务端地址
$host = '127.0.0.1';
$port = 65533;
if(($sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP)) === FALSE)
{
	exit('初始化socket资源错误: ' . socket_strerror(socket_last_error($sock)));
}
 
if(socket_connect($sock, $host, $port) === FALSE)
{
	exit('连接socket失败: ' . socket_strerror(socket_last_error($sock)));
}
 
$data = '';
// 循环读取指定长度的服务器响应数据
while($response = socket_read($sock, 4))
{
	$data .= $response;
}
socket_write($sock, '接收消息成功');
echo $data . PHP_EOL;
 
socket_close($sock);

//启动命令
php client.php
This entry was posted in 应用. Bookmark the permalink.

发表评论