本文由码农网 –
小峰原创翻译,转载请看清文末的转载要求,欢迎参与我们的付费投稿计划!

Socket介绍

实现客户端与服务端的连接: 

Socket 编程
套接字使用TCP提供了两台计算机之间的通信机制。
客户端程序创建一个套接字,并尝试连接服务器的套接字。
当连接建立时,服务器会创建一个 Socket 对象。客户端和服务器现在可以通过对
Socket 对象的写入和读取来进行通信。
java.net.Socket 类代表一个套接字,并且 java.net.ServerSocket
类为服务器程序提供了一种来监听客户端,并与他们建立连接的机制。
以下步骤在两台计算机之间使用套接字建立TCP连接时会出现:
服务器实例化一个 ServerSocket 对象,表示通过服务器上的端口通信。
服务器调用 ServerSocket 类的 accept()
方法,该方法将一直等待,直到客户端连接到服务器上给定的端口。
服务器正在等待时,一个客户端实例化一个 Socket
对象,指定服务器名称和端口号来请求连接。
Socket
类的构造函数试图将客户端连接到指定的服务器和端口号。如果通信被建立,则在客户端创建一个
Socket 对象能够与服务器进行通信。
在服务器端,accept() 方法返回服务器上一个新的 socket 引用,该 socket
连接到客户端的 socket。
连接建立后,通过使用 I/O
流在进行通信,每一个socket都有一个输出流和一个输入流,客户端的输出北京股票配资流连接到服务器端的输入流,而客户端的输入流连接到服务器端的输出流。
TCP
是一个双向的通信协议,因此数据可以通过两个数据流在同一时间发送.以下是一些类提供的一套完整的有用的方法来实现
socket。
ServerSocket 类的方法
服务器应用程序通过使用 java.net.ServerSocket
类以获取一个端口,并且侦听客户端请求。
ServerSocket 类有四个构造方法:
序号 方法描述
1 public ServerSocket(int port) throws IOException
创建绑定到特定端口的服务器套接字。
2 public ServerSocket(int port, int backlog) throws IOException
利用指定的 backlog 创建服务器套接字并将其绑定到指定的本地端口号。
3 public ServerSocket(int port, int backlog, InetAddress address) throws
IOException
使用指定的端口、侦听 backlog 和要绑定到的本地 IP 地址创建服务器。
4 public ServerSocket() throws IOException
创建非绑定服务器套接字。
创建非绑定服务器套接字。 如果 ServerSocket
构造方法没有抛出异常,就意味着你的应用程序已经成功绑定到指定的端口,并且侦听客户端请求。
这里有一些 ServerSocket 类的常用方法:
序号 方法描述
1 public int getLocalPort()
返回此套接字在其上侦听的端口。
2 public Socket accept() throws IOException
侦听并接受到此套接字的连接。
3 public void setSoTimeout(int timeout)
通过指定超时值启用/禁用 SO_TIMEOUT,以毫秒为单位。
4 public void bind(SocketAddress host, int backlog)
将 ServerSocket 绑定到特定地址(IP 地址和端口号)。
Socket 类的方法
java.net.Socket
类代表客户端和服务器都用来互相沟通的套接字。客户端要获取一个 Socket
对象通过实例化 ,而 服务器获得一个 Socket 对象则通过 accept()
方法的返回值。
Socket 类有五个构造方法.
序号 方法描述
1 public Socket(String host, int port) throws UnknownHostException,
IOException.
创建一个流套接字并将其连接到指定主机上的指定端口号。
2 public Socket(InetAddress host, int port) throws IOException
创建一个流套接字并将其连接到指定 IP 地址的指定端口号。
3 public Socket(String host, int port, InetAddress localAddress, int
localPort) throws IOException.
创建一个套接字并将其连接到指定远程主机上的指定远程端口。
4 public Socket(InetAddress host, int port, InetAddress localAddress,
int localPort) throws IOException.
创建一个套接字并将其连接到指定远程地址上的指定远程端口。
5 public Socket()
通过系统默认类型的 SocketImpl 创建未连接套接字
当 Socket 构造方法返回,并没有简单的实例化了一个 Socket
对象,它实际上会尝试连接到指定的服务器和端口。
下面列出了一些感兴趣的方法,注意客户端和服务器端都有一个 Socket
对象,所以无论客户端还是服务端都能够调用这些方法。
序号 方法描述
1 public void connect(SocketAddress host, int timeout) throws
IOException
将此套接字连接到服务器,并指定一个超时值。
2 public InetAddress getInetAddress()
返回套接字连接的地址。
3 public int getPort()
返回此套接字连接到的远程端口。
4 public int getLocalPort()
返回此套接字绑定到的本地端口。
5 public SocketAddress getRemoteSocketAddress()
返回此套接字连接的端点的地址,如果未连接则返回 null。
6 public InputStream getInputStream() throws IOException
返回此套接字的输入流。
7 public OutputStream getOutputStream() throws IOException
返回此套接字的输出流。
8 public void close() throws IOException
关闭此套接字。
InetAddress 类的方法
这个类表示互联网协议(IP)地址。下面列出了 Socket 编程时比较有用的方法:
序号 方法描述
1 static InetAddress getByAddress(byte[] addr)
在给定原始 IP 地址的情况下,返回 InetAddress 对象。
2 static InetAddress getByAddress(String host, byte[] addr)
根据提供融金汇银的主机名和 IP 地址创建 InetAddress。
3 static InetAddress getByName(String host)
在给定主机名的情况下确定主机的 IP 地址。
4 String getHostAddress()
返回 IP 地址字符串(以文本表现形式)。
5 String getHostName()
获取此 IP 地址的主机名。
6 static InetAddress getLocalHost()
返回本地主机。
7 String toString()
将此 IP 地址转换为 String。
Socket 客户端实例
如下的 GreetingClient 是一个客户端程序,该程序通过 socket
连接到服务器并发送一个请求,然后等待一个响应。
GreetingClient.java 文件代码:
// 文件名 GreetingClient.java

介绍

Socket用于进程间通信。进程间通信通常基于客户端—服务端模型。此时,客户端—服务端是可以彼此交互的应用程序。客户端和服务端之间的交互需要连接。Socket编程负责的就是为应用程序之间建立可进行交互的连接。

在本文中,我们将学习如何用PHP创建一个简单的客户端—服务端。我们还将学习如何客户端应用程序如何发送消息到服务端,以及如何从服务端接受消息。

图片 1

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

  1. 创建TCP服务端的
    ServerSocket

import java.net.;
import java.io.
;

使用代码

目的:开发一个客户端用于发送string消息到服务端,服务端将相同的信息反转后返回给客户端。

PHP服务器

第1步:设置变量,如“主机”和“端口”

$host = "127.0.0.1";
$port = 5353;
// No Timeout 
set_time_limit(0);

端口号可以是1024 -65535之间的任何正整数。

第2步:创建socket

$socket = socket_create(AF_INET, SOCK_STREAM, 0) or die("Could not create socket\n");

第3步:绑定socket到端口和主机

创建的socket资源绑定到IP地址和端口号。

$result = socket_bind($socket, $host, $port) or die("Could not bind to socket\n");

第4步:启动socket监听

在绑定到IP和端口后,服务端开始等待客户端的连接。在没有连接之前它就一直等下去。

$result = socket_listen($socket, 3) or die("Could not set up socket listener\n");

第5步:接受连接

这个函数会接受所建的socket传入的连接请求。在接受来自客户端socket的连接后,该函数返回另一个socket资源,实际上就是负责与相应的客户端socket通信。这里的“$spawn”就是负责与客户端socket通信的socket资源。

$spawn = socket_accept($socket) or die("Could not accept incoming connection\n");

到现在为止,我们已经准备好了服务端socket ,但实际上这个脚本并没有做任何事情。所以为了继续完成上述目标,我们将读取客户端socket消息,然后将接收到的消息反转后发回给客户端socket。

第6步:从客户端socket读取消息

$input = socket_read($spawn, 1024) or die("Could not read input\n");

第7步:反转消息

$output = strrev($input) . "\n";

第8步:发送消息给客户端socket

socket_write($spawn, $output, strlen ($output)) or die("Could not write output\n");

关闭socket

socket_close($spawn);
socket_close($socket);

这就完成了服务端。现在,我们学习如何创建PHP客户端。

PHP客户端

前两个步骤与服务端相同。

第1步:设置变量,如“主机”和“端口”

$host = "127.0.0.1";
$port = 5353;
// No Timeout 
set_time_limit(0);

注:这里的端口和主机应该和服务端中的定义是相同的。

第2步:创建socket

$socket = socket_create(AF_INET, SOCK_STREAM, 0) or die("Could not create socket\n");

第3步:连接到服务端

$result = socket_connect($socket, $host, $port) or die("Could not connect toserver\n");

此时和服务端不同,客户端socket不绑定端口和主机。相反,它连接到服务端socket,等待接受来自客户端socket的连接。这一步建立了客户端socket到服务端socket的连接。

第4步:写入服务端socket

socket_write($socket, $message, strlen($message)) or die("Could not send data to server\n");

在此步骤中,客户端socket的数据被发送到服务端socket。

第5步:阅读来自服务端的响应

$result = socket_read ($socket, 1024) or die("Could not read server response\n");
echo "Reply From Server  :".$result;

第6步:关闭socket

socket_close($socket);

完整的代码

服务端(server.php)

// set some variables
$host = "127.0.0.1";
$port = 25003;
// don't timeout!
set_time_limit(0);
// create socket
$socket = socket_create(AF_INET, SOCK_STREAM, 0) or die("Could not create socket\n");
// bind socket to port
$result = socket_bind($socket, $host, $port) or die("Could not bind to socket\n");
// start listening for connections
$result = socket_listen($socket, 3) or die("Could not set up socket listener\n");

// accept incoming connections
// spawn another socket to handle communication
$spawn = socket_accept($socket) or die("Could not accept incoming connection\n");
// read client input
$input = socket_read($spawn, 1024) or die("Could not read input\n");
// clean up input string
$input = trim($input);
echo "Client Message : ".$input;
// reverse client input and send back
$output = strrev($input) . "\n";
socket_write($spawn, $output, strlen ($output)) or die("Could not write output\n");
// close sockets
socket_close($spawn);
socket_close($socket);

客户端(client.php)

$host    = "127.0.0.1";
$port    = 25003;
$message = "Hello Server";
echo "Message To server :".$message;
// create socket
$socket = socket_create(AF_INET, SOCK_STREAM, 0) or die("Could not create socket\n");
// connect to server
$result = socket_connect($socket, $host, $port) or die("Could not connect to server\n");  
// send string to server
socket_write($socket, $message, strlen($message)) or die("Could not send data to server\n");
// get server response
$result = socket_read ($socket, 1024) or die("Could not read server response\n");
echo "Reply From Server  :".$result;
// close socket
socket_close($socket);

建立上述文件(server.php和client.php)后,执行如下操作:

  1. 复制www目录中的这些文件(假设WAMP),安置于C:\wamp。
  2. 打开Web浏览器,在地址栏中键入localhost 。
  3. 先浏览server.php然后client.php。

  在Internet上的主机一般运行了多个服务软件 ,
同时提供集中服务。每种服务都打开一个Socket , 并绑定一个端口山谷 ,
不同的端口对应于不同的服务。

  ServerSocket
:此类实现服务器套接字。服务器套接字请求通过网络传入,基于该请求执行某些操作,然后可能向请求者返回结果。

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);

许可证

这篇文章,以及任何相关的源代码和文件,是经过The Code Project Open
License (CPOL)许可的。

  tcp->http(可以用来做网站或者相关服务)

  其
accept()方法接受来自客户端的连接请求,并返回一个用于与Client
通信的Socket 对象。此后Server 的对象server 只要向该Socket
对象读写数据,就可以向远程的Client 读写数据。

     out.writeUTF("Hello from " + client.getLocalSocketAddress());
     InputStream inFromServer = client.getInputStream();
     DataInputStream in = new DataInputStream(inFromServer);
     System.bjrongjinhuiyin.com.out.println("服务器响应: " + in.readUTF());
     client.close();
  }catch(IOException e)
  {
     e.printStackTrace();
  }

  udp

下面是一个典型的创建Server端ServerSocket的过程。
  ServerSocket server=null;
  try {
     server=new ServerSocket(4700);
     //创建一个ServerSocket在端口4700监听客户请求
  }catch(IOException e){
     System.out.println(“can not listen to :”+e);
  }
  Socket socket=null;
  try {
    socket=server.accept();
    //accept()是一个阻塞的方法,一旦有客户请求,它就会返回一个Socket对象用于同客户进行交互
  }catch(IOException e){
    System.out.println(“Error:”+e);
  }

}
}
Socket 服务端实例
如下的GreetingServer 程序是一个服务器端应用程序,使用 Socket
来监听一个指定的端口。
GreetingServer.java 文件代码:
// 文件名 GreetingServer.java

Socket连接过程

  以上的程序是Server的典型工作模式,只不过在这里Server只能接收一个请求,接受完后Server就退出了。实际的应用中总是让它不停的循环接收,一旦有客户请求,Server总是会创建一个服务线程来服务新来的客户,而自己继续监听。程序中accept()是一个阻塞函数,所谓阻塞性方法就是说该方法被调用后,将等待客户的请求,直到有一个客户启动并请求连接到相同的端口,然后accept()返回一个对应于客户的socket。这时,客户方和服务方都建立了用于通信的socket,接下来就是由各个socket分别打开各自的输入/输出流。

import java.net.;
import java.io.
;

根据链接启动的方式以及本地套接字要连接的目标 ,
套节字之间的连接过程可以分为三个步骤:

  

public class GreetingServer extends Thread
{
private ServerSocket serverSocket;

1、服务器监听:是服务器端套接字并不定位具体的客户端套接字
, 而是处于等待连接的状态 ,实时监控网络状态。

  ServerSocket
类的构造方法:

public GreetingServer(int port) throws IOException
{
serverSocket = new ServerSocket(port);
serverSocket.setSoTimeout(10000);
}

2、客户端请求:是指由客户端的套接字提出连接请求,要连接的目标是服务器端的套接字。为此,客户端的套接字必须首先面熟它要连接的服务器的套接字,指出服务器套接字的地址和端口号
, 然后就像服务器端套接字提出连接请求。

ServerSocket()
          创建非绑定服务器套接字。
ServerSocket(int port)
          创建绑定到特定端口的服务器套接字。
ServerSocket(int port, int backlog)
          利用指定的 backlog 创建服务器套接字并将其绑定到指定的本地端口号。
ServerSocket(int port, int backlog, InetAddress bindAddr)
          使用指定的端口、侦听 backlog 和要绑定到的本地 IP 地址创建服务器。

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();
}
}
}

3、连接确认:是指当服务器端套接字监听到或者说接收到客户端套接字的连接请求,他就响应客户端套接字的请求,建立一个新的线程,把服务器端套接字的描述发给客户端
, 一旦客户确认了此描述 ,
连接就建立好了。而服务器端套接字继续处于监听状态,继续接收其他客户端接字的链接请求。

  ServerSocket 类的常用方法

一、测试环境:

 Socket accept()
          侦听并接受到此套接字的连接。
 void bind(SocketAddress endpoint, int backlog)
          将 ServerSocket 绑定到特定地址(IP 地址和端口号)。
 void close()
          关闭此套接字。
 InetAddress getInetAddress()
          返回此服务器套接字的本地地址。
 boolean isBound()
          返回 ServerSocket 的绑定状态。
 boolean isClosed()
          返回 ServerSocket 的关闭状态。

  服务器ip:xxx.xxx.xxx.1

简要代码:

  客户端ip: xxx.xxx.xxx.2

ServerSocket server = new ServerSocket( 有效端口号 );

二 测试过程:

Server client = server.accept(); // 在没有接收到客户端连接请求时,
accept
属于堵塞状态,接收到后继续                                                        //运行。

  客户端服务器将在本机(xxx.xxx.xxx.1)通过socket发送数据到服务端(xxx.xxx.xxx.2)的socket服务器上,服务端收到客户端发送的数据后返回一些给客户端.

if(client!=null){

  System.out.println(“有客户端连接上来了”);

  <?php

}

  //获取tcp协议号吗.

 

  $tcp = getprotobyname;

 2.TCP客户端的Socket

  //建立server端socket ,
创建并返回一个套接字,也称做一个通讯节点.一个典型的网络连接由2个套接字构成
, 一个运行在客户端 , 另一个运行在服务器端.

  Socket
类:此类实现客户端套接字(“套接字”)套接字是两台机器间通信的端点。用于将应用程序和端口连接起来。不同的端口确定连接到服务器的哪项服务上。

  $socket = socket_create(AF_INFT ,
SOCK_STREAM , $tcp);

  创建一个Socket类之后,通过调用 Socket 的getInputStream
方法从服务程序获得输入流传送来的消息;通过调用 getOutputStream
方法获得输出流来发送消息。

  //绑定要监听的ip和端口 ,
这里绑定的ip一定要写局域网ip ,
写成127.0.0.1客户端将无法与服务器端建议连接.

      创建 Socket:

  socket_bind($socket , ‘xxx.xxx.xxx.1’
, 10008);

      下面是一个典型的创建客户端Socket的过程。
   try{
     Socket socket=new
Socket(“127.0.0.1”,4700);
     //127.0.0.1是TCP/IP协议中默认的本机地址
   }catch(IOException e){
     System.out.println(“Error:”+e);
   }

  //监听端口

  这是最简单的在客户端创建一个Socket的一个小程序段,也是使用Socket进行网络通讯的第一步,程序相当简单,在这里不作过多解释了。在后面的程序中会用到该小程序段。

  socket_listen;

     
  注意,在选择端口时,必须小心。每一个端口提供一种特定的服务,只有给出正确的端口,才能获得相应的服务。0~1023的端口号为系统所保留,例如http服务的端口号为80,telnet服务的端口号为21,ftp服务的端口号为23,
所以我们在选择端口号时,最好选择一个大于1023的数以防止发生冲突。

  //初始化一个数据 , 和客户端通信

  在创建socket时如果发生错误,将产生IOException,在程序中必须对之作出处理。所以在创建Socket或ServerSocket是必须捕获或抛出例外。

  $buffer = “connect”;

  常用的构造方法:

  while{

  Socket()
          通过系统默认类型的 SocketImpl 创建未连接套接字
  Socket(InetAddress address, int port)
          创建一个流套接字并将其连接到指定 IP 地址的指定端口号。
  Socket(InetAddress address, int port, InetAddress localAddr, int localPort)
          创建一个套接字并将其连接到指定远程地址上的指定远程端口。
protected Socket(SocketImpl impl)
          使用用户指定的 SocketImpl 创建一个未连接 Socket。
  Socket(String host, int port)
          创建一个流套接字并将其连接到指定主机上的指定端口号。
  Socket(String host, int port, InetAddress localAddr, int localPort)
          创建一个套接字并将其连接到指定远程主机上的指定远程端口。

    //接受客户端请求过来的yigesocket连接

      
其中address、host和port分别是双向连接中另一方的IP地址、主机名和端口号,stream指明socket是流socket还是数据报socket,localPort表示本地主机的端口号,localAddr和bindAddr是本地机器的地址(ServerSocket的主机地址),impl是socket的父类,既可以用来创建serverSocket又可以用来创Socket。count则表示服务端所能支持的最大连接数。例如:
  Socket client = new Socket(“127.0.01.”, 80);
  ServerSocket server = new ServerSocket(80);

Author

发表评论

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