【翻译】java-TCP-socket网络编程1

  参考网址:http://tutorials.jenkov.com/java-networking/sockets.html

  我自己学习时做的一个总结,不妥之处请各位大哥指教,小弟先谢过!!

  JavaTCP网络基础(Java TCP Networking Basics)

  通常,客户机打开到服务器的TCP/IP连接。然后客户机开始与服务器通信。当客户端完成时,它会再次关闭连接。这里有一个例子:

  客户端可以通过打开的连接发送多个请求。实际上,客户机可以发送服务器准备接收的数据的数量。如果愿意,服务器也可以关闭连接。

  Java Socket's and ServerSocket's

  当客户机想要打开到服务器的TCP/IP连接时,它使用Java套接字进行操作。套接字被告知要连接什么IP地址和TCP端口,其余的由Java完成。
  如果您想启动一个服务器,在某个TCP端口上侦听来自客户机的传入连接,则必须使用Java ServerSocket。当客户端通过客户端套接字连接到服务器的ServerSocket时,服务器上的socket被分配到该连接。客户机和服务器现在进行套接字到套接字的通信。
  Socket和ServerSocket在后面的文章中有更详细的介绍。
  
  

  为了在Java中通过internet(通过TCP/IP)连接到服务器,您需要创建一个Java .net. socket并将其连接到服务器。或者,您也可以使用Java NIO SocketChannel,以防您更喜欢使用Java NIO。

  

 

   这个代码示例在端口80上以IP地址78.46.84.171连接到服务器。该服务器碰巧是我的web服务器(www.jenkov.com),而端口80是web服务器端口。

Socket socket = new Socket("78.46.84.171", 80);

  您还可以使用域名而不是IP地址,如下所示:

Socket socket = new Socket("jenkov.com", 80);

  

  要写入Java套接字,必须获得其OutputStream。这是过程:

Socket socket = new Socket("jenkov.com", 80);//新建一个socket
OutputStream out = socket.getOutputStream();//用socket的getOutPutStream获取输出

out.write("some data".getBytes());//写入想要发送的数据
out.flush();//缓冲数据并将其以更大的块发送
out.close();//发完了就关闭流

socket.close();//全部交互结束,关闭socket。
  就是这么简单!
  当您非常非常希望将数据通过internet发送到服务器时,不要忘记调用flush()。操作系统中的底层TCP/IP实现可以缓冲数据并将其以更大的块发送,以适应TCP/IP数据包的大小。
  

  要从Java套接字读取数据,需要获得其InputStream。这是过程:

Socket socket = new Socket("jenkov.com", 80);//新建一个socket
InputStream in = socket.getInputStream();//用socket的getInputStream获取输入

int data = in.read();//读取数据
//... read more data...

in.close();//关闭输入流
socket.close();//关闭socket连接
  很简单,对吧?
  请记住,在套接字的InputStream返回-1之前,您不能总是从它读取数据,就像在读取文件时一样。原因是只有当服务器关闭连接时才返回-1。但是服务器可能并不总是关闭连接。也许您希望通过同一连接发送多个请求。在这种情况下,关闭连接是非常愚蠢的。
  反,您必须知道从套接字的InputStream读取多少字节。这可以通过告诉服务器它正在发送多少字节来完成,或者通过查找一个特殊的数据结束字符来完成
 
  我发现这里很容易弄混,说了这么多,那到底是哪里读到哪里???

  

  考虑上面的代码,应该思路就清晰了。

  代理服务器:

   

    

  上面看懂了,,,那我接着说。。。。

  

 

   为了实现通过TCP/IP侦听来自客户机的传入连接的Java服务器,您需要使用Java .net. serversocket。如果您喜欢使用Java NIO而不是Java联网(标准API),那么您还可以使用ServerSocketChannel而不是Java .net. serversocket。

   

  下面是一个简单的代码示例,它创建了一个监听端口9000的ServerSocket:

ServerSocket serverSocket = new ServerSocket(9000);

  监听到来的连接请求:

   为了接受传入的连接,必须调用ServerSocket.accept()方法。accept()方法返回一个套接字,其行为与普通Java套接字类似。以下是它的样子:

ServerSocket serverSocket = new ServerSocket(9000);//创建serverSocket

boolean isStopped = false;//假如没有停止传输,持续监听
while(!isStopped){
    Socket clientSocket = serverSocket.accept();//监听

    //do something with clientSocket
}
  对于对accept()方法的每次调用,只打开一个传入连接。
  此外,只能在运行服务器的线程调用accept()时接受传入的连接。线程在此方法之外执行时,没有客户机可以连接。因此,“接受”线程通常将传入的连接(套接字的)传递给工作线程池,然后工作线程池与客户机通信。有关多线程服务器设计的更多信息,请参阅教程跟踪Java多线程服务器。

   

  一旦客户端请求完成,并且没有从该客户端接收到进一步的请求,您必须关闭该套接字,就像关闭普通的客户端套接字一样。这是通过调用:

socket.close();

  一旦这台服务器被关闭了,你还得关闭ServerSocket。这是通过下面的代码:

serverSocket.close();

  那么就先写到这里。

 

posted @ 2018-10-31 00:01  清凌  阅读(253)  评论(0编辑  收藏  举报