ソケットは私たちにとって非常に実用的です。以下はこの研究のためのメモです。これは主に、例外タイプ、対話原則、ソケット、サーバーソケット、およびマルチスレッドに分かれています。リアルタイム アプリケーションやリアルタイム ゲームの場合、HTTP プロトコルではニーズを満たせないことがよくあります。現時点では、Socket は私たちにとって非常に実用的です。以下はこの研究のためのメモです。主に、例外の種類、相互作用の原則、Socket、ServerSocket、およびマルチスレッドの観点から説明されます。
例外タイプ Socket の内容を理解する前に、まず、関連する例外タイプのいくつかを理解する必要があります。次の 4 つの型はすべて IOException を継承しているため、その多くは IOException を直接ポップアップする可能性があります。
UnkownHostException: ホスト名またはIPエラー
ConnectException: サーバーが接続を拒否しました、サーバーが起動しませんでした、(キュー数を超えました、接続が拒否されました)SocketTimeoutException: 接続がタイムアウトしました
BindException: Socketオブジェクト指定されたローカル IP アドレスまたはポートにバインドすることはできません
対話プロセス Socket と ServerSocket の間の対話については、以下の図で詳細かつ明確に説明されていると思います。
Socket()Socket(InetAddress address, int port)throws UnknownHostException, IOException
Socket(InetAddress address, int port, InetAddress localAddress, int localPort)th rowsIOExceptionソケット ( String host, int port)throws UnknownHostException, IOException
Socket(String host, int port, InetAddress localAddress, int localPort)throws IOException
パラメーターのない最初のコンストラクターを除き、他のコンストラクターはサーバーとの接続を確立しようとします。 。失敗した場合は、IOException エラーがスローされます。成功すると、Socket オブジェクトが返されます。
getInetAddress(); リモートサーバーのIPアドレスgetPort(); リモートサーバーのポート
getLocalAddress() ローカルクライアントのIPアドレスgetLocalPort()ローカルクライアントの
getInputStream() ; 入力ストリームを取得する
getOutStream(); 出力ストリームを取得する
これらのメソッドの中で、最も重要なものは getInputStream() と getOutputStream() であることに注意してください。
isClosed(); //接続が閉じられているかどうか、閉じられている場合はtrueを返し、それ以外の場合はfalseを返しますisConnect(); //以前に接続されていた場合はtrueを返します。それ以外の場合は return false
isBound(); //Socket がローカルポートにバインドされている場合は true を返し、それ以外の場合は false を返します
Socket が接続されているかどうかを確認したい場合は、次のステートメントが良い方法です。 。
多くの場合、わかりません取得する入力ストリームの内容 読み取りを完了するまでにどのくらい時間がかかりますか?以下に一般的なメソッドをいくつか示します。
注:
1. バックログクライアント接続リクエストのキューの長さ。ポートが占有されている場合、または特定のポートを使用する権限がない場合は、BindException エラーがスローされます。たとえば、ポート 1 ~ 1023 には、管理者にバインドする権限が必要です。 3. ポートが 0 に設定されている場合、システムは自動的にポートを割り当てます。 4. bindAddr用于绑定服务器IP,为什么会有这样的设置呢,譬如有些机器有多个网卡。 5. ServerSocket一旦绑定了监听端口,就无法更改。ServerSocket()可以实现在绑定端口前设置其他的参数。 单线程的ServerSocket例子 多线程的ServerSocket 多线程的好处不用多说,而且大多数的场景都是多线程的,无论是我们的即时类游戏还是IM,多线程的需求都是必须的。下面说说实现方式: 主线程会循环执行ServerSocket.accept(); 当拿到客户端连接请求的时候,就会将Socket对象传递给多线程,让多线程去执行具体的操作; 实现多线程的方法要么继承Thread类,要么实现Runnable接口。当然也可以使用线程池,但实现的本质都是差不多的。 这里举例: 下面代码为服务器的主线程。为每个客户分配一个工作线程: 当然这里的重点在于如何实现Handler这个类。Handler需要实现Runnable接口: 当然是先多线程还有其它的方式,譬如线程池,或者JVM自带的线程池都可以。这里就不说明了。public void service(){
while(true){
Socket socket=null;
try{
socket=serverSocket.accept();//从连接队列中取出一个连接,如果没有则等待
System.out.println("新增连接:"+socket.getInetAddress()+":"+socket.getPort());
...//接收和发送数据
}catch(IOException e){e.printStackTrace();}finally{
try{
if(socket!=null) socket.close();//与一个客户端通信结束后,要关闭Socket
}catch(IOException e){e.printStackTrace();}
}
}
}
public void service(){
while(true){
Socket socket=null;
try{
socket=serverSocket.accept(); //主线程获取客户端连接
Thread workThread=new Thread(new Handler(socket)); //创建线程
workThread.start(); //启动线程
}catch(Exception e){
e.printStackTrace();
}
}
}
class Handler implements Runnable{
private Socket socket;
public Handler(Socket socket){
this.socket=socket;
}
public void run(){
try{
System.out.println("新连接:"+socket.getInetAddress()+":"+socket.getPort());
Thread.sleep(10000);
}catch(Exception e){e.printStackTrace();}finally{
try{
System.out.println("关闭连接:"+socket.getInetAddress()+":"+socket.getPort());
if(socket!=null)socket.close();
}catch(IOException e){
e.printStackTrace();
}
}
}
}
以上がJava でのソケット プログラミングの例を共有する (写真)の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。