澳门新浦京电子游戏socket

最近在做的项目有一项需要耗时任务在后台运行的功能,虽然PHP并不是非常适合做常驻后台的守护进程,但是由于项目主要代码都是基于PHP实现,如果运行在后台的守护进程改换别的语言会非常不方便。所以不可避免会涉及到Web端和Daemon部分的通信,Socket是一个不错的方式。

网络编程——基于TCP协议的Socket编程,基于UDP协议的Socket编程,socketudp

Socket编程

目前较为流行的网络编程模型是客户机/服务器通信模式

客户进程向服务器进程发出要求某种服务的请求,服务器进程响应该请求。如图所示,通常,一个服务器进程会同时为多个客户端进程服务,图中服务器进程B1同时为客户进程A1、A2和B2提供服务。

 

澳门新浦京电子游戏 1

Socket概述

①  
所谓Socket通常也称作“套接字”,用于描述IP地址和端口,是一个通信链的句柄。应用程序通常通过“套接字”向网络发出请求或者应答网络请求。

②   Socket是连接运行在网络上的两个程序间的双向通信的端点。

③   网络通讯其实指的就是Socket间的通讯。

④   通讯的两端都有Socket,数据在两个Socket之间通过IO来进行传输。

 

使用Socket进行网络通信的过程

①  
服务器程序将一个套接字绑定到一个特定的端口,并通过此套接字等待和监听客户的连接请求。

②   客户程序根据服务器程序所在的主机和端口号发出连接请求。

③  
如果一切正常,服务器接受连接请求。并获得一个新的绑定到不同端口地址的套接字。

④   客户和服务器通过读、写套接字进行通讯。

澳门新浦京电子游戏 2

 

基于TCP协议的Socket编程

①   创建TCP服务端步骤:

a)         创建一个ServerSocket对象

b)         调用accept()方法接受客户端请求

c)         从Socket中获取I/O流

d)         对I/O流进行读写操作,完成与客户端的交互

e)         关闭I/O流和Socket

②   创建TCP客户端步骤:

a)         创建一个Socket对象

b)         从Socket中获取I/O流

c)         对I/O流进行读写操作,完成与服务端的交互

d)         关闭I/O流和Socket

注:客户端和服务端进行数据传输时,客户端的输入流对应服务端的输出流,客户端的输出流对应服务端的输入流。

 

示例:创建一个客户端与服务端通信的例子

包名:com.iotek.tcpsocket

服务端:

 1         // 1.创建一个ServerSocket对象
 2         ServerSocket serverSocket = new ServerSocket(8888);
 3         // 2.调用accept()方法接受客户端请求
 4         Socket socket = serverSocket.accept();
 5         System.out.println(socket.getInetAddress().getHostAddress() + "连接成功");
 6         // 3.获取socket对象的输入输出流
 7         BufferedReader br = new BufferedReader(new InputStreamReader(
 8                 socket.getInputStream()));
 9 
10         PrintWriter pw = new PrintWriter(socket.getOutputStream(), true);
11         String line = null;
12         // 读取客户端传过来的数据
13         while ((line = br.readLine()) != null) {
14             if (line.equals("over")) {
15                 break;
16             }
17             System.out.println(line);
18             pw.println(line.toUpperCase());
19         }
20 
21         pw.close();
22         br.close();
23         socket.close();
24         System.out.println(socket.getInetAddress().getHostAddress() + "断开连接");

 

客户端:

 1         Socket socket = new Socket("127.0.0.1", 8888);
 2         BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
 3 
 4         PrintWriter pw = new PrintWriter(socket.getOutputStream(), true);
 5         BufferedReader reader = new BufferedReader(new InputStreamReader(
 6                 socket.getInputStream()));
 7         while (true) {
 8             String line = br.readLine();// 获取键盘所输入的字符串
 9             pw.println(line);
10             if (line.equals("over")) {
11                 break;
12             }
13             System.out.println(reader.readLine());// 获取服务端传过来的大写字符串
14         }
15         reader.close();
16         br.close();
17         pw.close();
18         socket.close();

为了更直观的看见通信过程,将2个java程序复制到E盘根目录下,用命令行的形式来运行。

澳门新浦京电子游戏 3

打开cmd,编译java,步骤

① 进入e盘。  e:

② 编译所有java文件。 javac –d . *.java

③ 打开服务端。    java com.iotek.tcpsocket.TCPServer

④ 再打开一个cmd命令行用于打开客户端java com.iotek.tcpsocket.TCPClient

 连接成功

澳门新浦京电子游戏 4

在客户端输入hello回车之后测试成功。

澳门新浦京电子游戏 5

输入over,断开连接

澳门新浦京电子游戏 6

 

基于UDP协议的Socket编程

① 创建发送端

a)    
建立DatagramSocket对象。该端点建立,系统会随机分配一个端口。如果不想随机配置,可以手动指定。

b)     将数据进行packet包的封装,必须要指定目的地地址和端口。

c)     通过socket服务的send方法将该包发出。

d)     将socket关闭。

② 创建接收端

a)     建立DatagramSocket对象。要监听一个端口。

b)     通过socket的receive方法将数据存入数据包中。

c)    
通过数据包dp的方法getData()、getAddress()、getPort()等方法获取包中的指定信息。

d)     将socket关闭。

 

示例:创建一个发送与接收的例子

发送端:UDPDemo1

 1         DatagramSocket socket = new DatagramSocket();
 2         String str = "i love you";
 3         // 把数据进行封装到数据报包中
 4         DatagramPacket packet = new DatagramPacket(str.getBytes(),
 5                 str.length(), InetAddress.getByName("localhost"), 6666);
 6         socket.send(packet);// 发送
 7 
 8         byte[] buff = new byte[100];
 9         DatagramPacket packet2 = new DatagramPacket(buff, 100);
10         socket.receive(packet2);
11         System.out.println(new String(buff, 0, packet2.getLength()));
12         socket.close();

 

接收端:UDPDemo2

 1         // 先接收数据
 2         DatagramSocket socket = new DatagramSocket(6666);
 3         byte[] buff = new byte[100];
 4         DatagramPacket packet = new DatagramPacket(buff, 100);
 5         socket.receive(packet);// 接受传来的数据包
 6         System.out.println(new String(buff, 0, packet.getLength()));
 7 
 8         // 发送数据
 9         String str = "me too";
10         DatagramPacket packet2 = new DatagramPacket(str.getBytes(),
11                 str.length(), packet.getAddress(), packet.getPort());
12         socket.send(packet2);
13         socket.close();

 

将2个java程序复制到E盘根目录下,用命令行的形式来运行。

澳门新浦京电子游戏 7

打开cmd,编译java,步骤:

① 进入e盘。  e:

②   编译以UDP开头的文件。 javac –d . UDP*.java

③   先运行接收端。  java com.iotek.tcpsocket.UDPDemo2

④   重新打开一个命令行,运行发送端。  java com.iotek.tcpsocket.UDPDemo1

澳门新浦京电子游戏 8

Socket编程 目前较为流行的网络编程模型是客户机/服务器通信模式…

第一部分概念理解

Socket是什么

socket的英文原义是“孔”或“插座”。作为BSD
UNIX的进程通信机制,取后一种意思。通常也称作”套接字”,用于描述IP地址和端口,是一个通信链的句柄。在Internet上的主机一般运行了多个服务软件,同时提供几种服务。每种服务都打开一个Socket,并绑定到一个端口上,不同的端口对应于不同的服务。

以上内容来自百度百科

简单说来,socket可以帮助不同的服务在不同的端口进行通信。

1.什么是socket

socket称为”嵌套字”,是用于网络通信的方法。它的实质并不是一种协议,没有规定计算机应当怎么样传递消息,只是给程序员提供了一个发送消息的接口,程序员使用这个接口提供的方法,发送与接收消息。

PHP中的实现

### 服务端

<?php 
set_time_limit(0);
// 设置主机和端口
$host = "127.0.0.1";
$port = 12387;
// 创建一个tcp流
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP) 
    or die("socket_create() failed:" . socket_strerror(socket_last_error()));

// 设置阻塞模式
socket_set_block($socket) 
    or die("socket_set_block() failed:" . socket_strerror(socket_last_error()));  

// 绑定到端口
socket_bind($socket, $host, $port) 
    or die("socket_bind() failed:" . socket_strerror(socket_last_error()));

// 开始监听
socket_listen($socket, 4) 
    or die("socket_listen() failed:" . socket_strerror(socket_last_error()));

echo "Binding the socket on $host:$port ... n";

while (true) {

    // 接收连接请求并调用一个子连接Socket来处理客户端和服务器间的信息
    if (($msgsock = socket_accept($socket)) < 0) {
        echo "socket_accept() failed:" . socket_strerror(socket_last_error());
    }else{
        // 读数据
        $out = '';
        while($buf = socket_read($msgsock,8192)){
            $out .= $buf;
        }

        // 写数据
        $in = "数据是 $out";
        socket_write($msgsock, $in, strlen($in));
    }
    // 结束通信
    socket_close($msgsock);
}
socket_close($socket);
?>

服务端主要进行了以下步骤:

  • 创建Socket的监听,等待连接
  • 当链接到来时,开启一个子连接处理IO
  • 接收来自客户端的传输数据
  • 将结果写回给客户端

2.通信过程

每一个应用或者说服务,都有一个端口。比如DNS的53端口,http的80端口。我们能由DNS请求到查询信息,是因为DNS服务器时时刻刻都在监听53端口,当收到我们的查询请求以后,就能够返回我们想要的IP信息。所以,从程序设计上来讲,应该包含以下步骤:

Socket通信过程如下:

1.服务端利用Socket监听端口;
2.客户端发起连接;
3.服务端返回信息,建立连接,开始通信;
4.客户端,服务端断开连接。

客户端

<?php 
set_time_limit(0);
$host = "127.0.0.1";  
$port = 12387;

// 创建一个tcp流
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP) 
    or die("socket_create() failed:" . socket_strerror(socket_last_error()));

echo "try to connect to $host:$port...n";
$result = socket_connect($socket, $host, $port)
    or die("socket_connect() failed:" . socket_strerror(socket_last_error()));

$in = "hello n";
if(!socket_write($socket, $in, strlen($in))) {
    echo "socket_write() failed:" . socket_strerror($socket);
}else {
    echo "发送成功!n";
}

$out = '';
while($buf = socket_read($socket, 8192)) {
    $out .= $buf;
}
echo "接受内容为:$out n";
socket_close($socket);
?>

客户端主要有以下步骤:

  • 连接到服务端Socket
  • 向服务端写数据
  • 接收来自服务端的数据

第二部分、各协议的区别

TCP/IP SOCKET HTTP

网络七层由下往上分别为物理层、数据链路层、网络层、传输层、会话层、表示层和应用层

其中物理层、数据链路层和网络层通常被称作媒体层,是网络工程师所研究的对象;

传输层、会话层、表示层和应用层则被称作主机层,是用户所面向和关心的内容。

http协议 对应于应用层
tcp协议 对应于传输层
ip协议 对应于网络层

三者本质上没有可比性。 何况HTTP协议是基于TCP连接的。

TCP/IP是传输层协议,主要解决数据如何在网络中传输;而HTTP是应用层协议,主要解决如何包装数据。

我们在传输数据时,可以只使用传输层(TCP/IP),但是那样的话,由于没有应用层,便无法识别数据内容,如果想要使传输的数据有意义,则必须使用应用层协议,应用层协议很多,有HTTP、FTP、TELNET等等,也可以自己定义应用层协议。WEB使用HTTP作传输层协议,以封装HTTP文本信息,然后使用TCP/IP做传输层协议将它发送到网络上。

Socket是对TCP/IP协议的封装,Socket本身并不是协议,而是一个调用接口(API),通过Socket,我们才能使用TCP/IP协议。

socket原理

概念

套接字(socket)是通信的基石,是支持TCP/IP协议的网络通信的基本操作单元。它是网络通信过程中端点的抽象表示,包含进行网络通信必须的五种信息:连接使用的协议,本地主机的IP地址,本地进程的协议端口,远地主机的IP地址,远地进程的协议端口。

应用层通过传输层进行数据通信时,TCP会遇到同时为多个应用程序进程提供并发服务的问题。多个TCP连接或多个应用程序进程可能需要通过同一个
TCP协议端口传输数据。为了区别不同的应用程序进程和连接,许多计算机操作系统为应用程序与TCP/IP协议交互提供了套接字(Socket)接口。应用层可以和传输层通过Socket接口,区分来自不同应用程序进程或网络连接的通信,实现数据传输的并发服务。

建立

建立Socket连接至少需要一对套接字,其中一个运行于客户端,称为ClientSocket,另一个运行于服务器端,称为ServerSocket。

套接字之间的连接过程分为三个步骤:服务器监听,客户端请求,连接确认
1.服务器监听:服务器端套接字并不定位具体的客户端套接字,而是处于等待连接的状态,实时监控网络状态,等待客户端的连接请求。
2.客户端请求:指客户端的套接字提出连接请求,要连接的目标是服务器端的套接字。为此,客户端的套接字必须首先描述它要连接的服务器的套接字,指出服务器端套接字的地址和端口号,然后就向服务器端套接字提出连接请求。
3.连接确认:当服务器端套接字监听到或者说接收到客户端套接字的连接请求时,就响应客户端套接字的请求,建立一个新的线程,把服务器端套接字的描述发给客户端,一旦客户端确认了此描述,双方就正式建立连接。而服务器端套接字继续处于监听状态,继续接收其他客户端套接字的连接请求。

澳门新浦京电子游戏 9

基本TCP客户—服务器程序设计基本框架

常见的套接字的创建方式

常用的Socket类型有两种:流式Socket(SOCK_STREAM)和数据报式Socket(SOCK_DGRAM)。流式是一种面向连接的Socket,针对于面向连接的TCP服务应用;数据报式Socket是一种无连接的Socket,对应于无连接的UDP服务应用

1.创建嵌套字
socket(int af,int type,int protocol);

socket函数接受3个参数.第一个参数(af)指定地址族,对于TCP/IP协议的套接字,它只能是AF_INET(也可以写成PF_INET);第二个参数(type)指定Socket类型,对于1.1版本的Socket,他只支持两种类型的套接字,SOCKE_STREAM指定产生流式套接字,SOCK_DGRAM产生数据报套接字;第三个参数(protocol)是与特定的地址家族相关的协议,如果指定为0,那么系统就会根据地址格式和套接类别,自动选择一个合适的协议.这是推荐使用的一种选择协议的方法.

如果socket函数调用成功,他就会返回一个新的socket数据类型的套接字描述符;如果调用失败,这个函数返回一个INVALID_SOCKET值,错误信息可以通过WSAGetLastError函数返回.

2.建立地址与嵌套字的关系
bind(sockid, local addr, addrlen)
3.服务器端监听客户端请求
listen( Sockid ,quenlen)

建立服务器/客户端的连接 (面向连接TCP)

1.客户端请求连接
Connect(sockid, destaddr, addrlen)
2.服务器端等待从编号为Sockid的Socket上接收客户连接请求
newsockid=accept(Socked,Clientaddr, paddrlen)

发送/接收数据

1.面向连接:
send(sockid, buff, bufflen) 
recv( )
2.面向无连接:
sendto(sockid,buff,…,addrlen) 
recvfrom( )

释放套接字

close(socked)

发表评论

电子邮件地址不会被公开。 必填项已用*标注