socket实现C-S

第一、建立计算机两者之间的关系


    java有很多的API支持网络编程,这里我们主要讲解Socket。其实java已经相当简化了网络编程模式。您不用太了解网络的协议和底层实现。(当然,有时间一定要研究一下)java提供ServerSocket类来支持。

当你ServerSocket serverSocket = new ServerSocket (8888)就已经建立了一个固定的位置可以让其它的计算机来访问你了。这里要稍微补充一下端口的支持,端口是为了唯一标识每台计算机唯一服务的,另外端口号是从0~65535之间的,前1024个端口已经被Tcp/Ip 作为保留端口,因此你所分配的端口只能是1024个之后的。好了,这样服务器端已经建立好了。接着我们开始建立客户端,java同样提供了Socket对象来支持,只要客户端创建了Socket client = new Socket(InetAddress.getLocalHost(),8888),

客户端必须知道服务器的地址,java提供了InetAddress.getLocalHost()静态方法来获得服务器地址。好了,到目前为止两台计算机之间的关系已经建立好了。

第二、数据的传输

   网络编程和I/O总是分不开的,java提供了很好的流机制来方便我们对字节流和Unicode的读写。也提供了数据缓冲哦你的读写。

BufferedReader br=new BufferedReader(new InputStreamReader(serverSocket.getInputStrea()));

PrintWriter out=new PrintWriter(serverSocket.getOutputStream());

上面两行语句建立流缓冲并把原始字节流转换成Unicode来进行操作,而原始的字节流有Socket的getInputStream()和getOutputStream()两个方法来获得输入和输出。掌握了一些基本概念和操作的工具我们就可以做一个简单的例子了。

1、建立服务端

   /**
* @author licheng
* @date 09-09-05
* @version 1.0
* @function 创建服务端
* */

package com.licheng.word.socket;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;

public class MyServer {

/**
* @param args
*/
public static void main(String[] args) throws IOException{
ServerSocket serverSocket = new ServerSocket(8888);    //建立服务端固定地址
Socket client = serverSocket.accept();    //侦听并接受到此套接字的连接
BufferedReader br = new BufferedReader(new InputStreamReader(client.getInputStream()));
PrintWriter out = new PrintWriter(client.getOutputStream());
while (true) {
   String str = br.readLine();
   System.out.println(str);
   out.println("read...");
   out.flush();
   if ("stop".equals(str)) {   //如果客户端传来的是stop就终止它
    break;
   }
}
client.close(); //关闭套接字
}

}

2、建立客户端

/**
* @author licheng
* @date 09-09-05
* @version 1.0
* @function 创建客户端
* */

package com.licheng.word.socket;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.Socket;

public class Client {

private static Socket serverSocket;

public static void main(String[] args) throws IOException{
serverSocket = new Socket(InetAddress.getLocalHost(),8888);    //获取服务器端的链接
BufferedReader in=new BufferedReader(new InputStreamReader(serverSocket.getInputStream()));
PrintWriter out=new PrintWriter(serverSocket.getOutputStream());
BufferedReader wt=new BufferedReader(new InputStreamReader(System.in));
while(true){
   String str = wt.readLine();
   out.println(str);
   out.flush();
   if(str.equals("stop")){
   break;
   }
   System.out.println(in.readLine());
   }
   serverSocket.close();
}
}

客户机代码则是接受客户键盘输入,并把该信息输出,然后输出"stop"用来做退出标识。

这个程序只是简单的两台计算机之间的通讯.如果是多个客户同时访问一个服务器呢?你可以试着再运行一个客户端,结果是会抛出异常的.那么多个客户端如何实现呢?

我们来简单的分析一下,客户端和服务器就像一根线一样连接着,客户端和服务器端的主要通道就是Socket,服务器是通过accept()方法来同意是否连接客户端。那么这样我们就用多跟连线就可以解决这个问题了,程序改成如下


/**
* @author licheng
* @date 09-09-05
* @version 1.0
* @function 创建服务端
* */

package com.licheng.word.socket;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;

public class MyServer {

/**
* @param args
*/
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = new ServerSocket(8888); // 建立服务端固定地址
while (true) {
   Socket client = serverSocket.accept(); // 侦听并接受到此套接字的连接
   BufferedReader br = new BufferedReader(new InputStreamReader(client
     .getInputStream()));
   PrintWriter out = new PrintWriter(client.getOutputStream());
   while (true) {
    String str = br.readLine();
    System.out.println(str);
    out.println("read...");
    out.flush();
    if ("stop".equals(str)) { // 如果客户端传来的是stop就终止它
     break;
    }
   }
   client.close(); // 关闭套接字
}
}
}

这样我们就完成了多个用户的之间的交互。可是问题又来了,那么排队执行怎么办,没关系,我们再分析一下,也就是说当一个客户和服务器完成一次通讯之后下一个客户才可以进来和服务器交互.无法做到同时服务.那么要如何才能同时达到既能相互之间交流又能同时交流呢?很显然这是一个并行执行的问题了.这时候我们应该想到线程是最好的解决方案。

要创建线程要么直接继承Thread要么实现Runnable接口,然后把main函数里面的方法写到run里面就可以了。

/**
* @author licheng
* @date 09-09-05
* @version 1.0
* @function 创建服务端,线程安全
* */

package com.licheng.word.socket;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;

public class MyServer extends Thread {

private Socket client;

public MyServer(Socket client) {
this.client = client;
}

@Override
public void run() {
try {
   BufferedReader in = new BufferedReader(new InputStreamReader(client
     .getInputStream()));
   PrintWriter out = new PrintWriter(client.getOutputStream());
   while (true) {
    String str = in.readLine();
    System.out.println(str);
    out.println("read....");
    out.flush();
    if (str.equals("stop")) {
     break;
    }
   }
   client.close();
} catch (IOException e) {
   e.printStackTrace();
} finally {
}
}

/**
* @param args
*/
public static void main(String[] args) throws IOException {
ServerSocket server=new ServerSocket(8888);
while(true){
MyServer mu = new MyServer(server.accept());
mu.start();
}
}

你可能感兴趣的:(java,C++,c,socket,C#)