现在的位置: 首页 > 综合 > 正文

网络编程(2)–TCP通信

2018年04月06日 ⁄ 综合 ⁄ 共 8636字 ⁄ 字号 评论关闭

1 .

public class  Server

{

  public static void main(String[] args) throws IOException

 {

    ServerSocket  ss = new ServerSocket(30000);

    while(true)

   {

     Socket  s = ss.accept();

     PrintStream ps = new PrintStream(s.getOutputStream());

     ps.println("您好,收到了服务器的新年祝福");

     ps.close();

     s.close();

   }

  }

}

 

public class Client

{

   public static void main(String[] args) throws IOException

  {

   Socket socket =new Socket("127.0.0.1",30000);

   BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));

   String line = br.readLine();

   System.out.println("来自服务器的数据:"+line);

   br.close();

  socket.close();

  }

}

 

 

Socket s = new Socket();

s.connect(new InetAddress(host,port),10000);

 

2 加入多线程

  public class MyServer

 {

    public static ArrayList<Socket>  socketList  =  new ArrayList<Socket>();

    public static void main(String[] args) throws IOException

   {

     ServerSocket  ss = new ServerSocket(30000);

    while(true)

    {

      Socket s = ss.accept();

      socketList.add(s);

      new Thread(new ServerThread(s)).start();

   }

  }

 }

 

public class ServerThread implements Runnable

{

   Socket s = null;

   BufferedReader br=null;

  public ServerThread(Socket s) throws IOException

  {

  this.s = s;

  br = new BufferedReader(new InputStreamReader(s.getInputStream()));

  }

 public void run()

 {

   try

  {

   String content = null;

   while((content = readFromClient())!=null)

  {

    for(Socket s : MyServer.socketList)

    {

      PrintStream ps = new PrintStream(s.getOutputStream());

      ps.println(content);

    }

  }

   }

  catch(IOException e)

  {

    //e.printStackTrace();

  }

 }

private String readFromClient()

 {

  try

  {

   return br.readLine();

   }

   catch(IOException e)

  {

    MyServer.socketList.remove(s);

 }

 return null;

 }

}

 

public class MyClient

{

  public static void main(String[] args) throws Exception

  {

    Socket s = new Socket("127.0.0.1",30000);

    new Thread(new ClientThread(s)).start();

    PrintStream ps = new PrintStream(s.getOutputStream());

    String line = null;

    BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

    while((line = br.readLine()) != null)

    {

      ps.println(line);

   }

 }

}

 

public class ClientThread implements Runnable

{

  private Socket s;

  BufferedReader br = null;

  public ClientThread(Socket s) throws IOException

 {

   this.s =s;

   br = new BufferedReader(new InputStreamReader(s.getInputStream()));

 }

 public void run()

{

  try

  {

     String  content = null;

    while((content = br.readLine()) != null)

    {

      System.out.println(content);

    }

  }

  catch(Exception e)

  {

     e.printStackTrace();

  }

 }

}

 

3  记录用户信息

  public interface YeekuProtocol

{

   int PROTOCOL_LEN = 2;
 //下面是一些协议字符串,服务器和客户端交换的信息
 //都应该在前、后添加这种特殊字符串。
 String MSG_ROUND = "§γ";
 String USER_ROUND = "∏∑";
 String LOGIN_SUCCESS = "1";
 String NAME_REP = "-1";
 String PRIVATE_ROUND = "★【";
 String SPLIT_SIGN = "※";

}

 

public class  YeekuMap<K,V> extends HashMap<K,V>

{

   public void removeByValue(Object value)

  {

     for(Object key : keySet())

    {

      if(get(key) == value)

      {

       remove(key);

       break;

      }

   }

  }

public Set<V> valueSet()

 {

   Set<V>  result = new HashSet<V>();

   for(K key : keySet())

   {

    result.add(get(key));

   }

   return result;

}

 

public K getKeyByValue(V val)

{

   for(K key : keySet())

   {

     if(get(key).equals(val) && get(key) == val)

     {

      return key;

     }

   }

  return null;

}

 

public V put(K key,V value)

{

  for(V val : valueSet())

 {

    if(val.equals(value) && val.hasCode()==value.hashCode())

    {

      throw  new   RuntimeException("MyMap 实例中不允许有重复value");

    }

 

}

return super.put(key,value);

}

}

 

public class Server

{

  private static final int SERVER_PORT = 30000;

  public static YeekuMap<String, PrintStream>  clients = new YeekuMap<String,PrintStream>();

  public void init()

 {

  ServerSocket ss = null;

  try

  {

    ss = new ServerSocket(SERVER_PORT);

   while(true)

   {

     Socket  socket = ss.accept();

     new ServerThread(socket).start();

   }

   }

  catch(IOException ex)

  {

   System.out.println("服务器启动失败,是否端口"+SERVER_PORT+"已被占用");

  }

  finally

  {

    try

    {

       if(ss != null)

       {

          ss.close();

       }

    }

   catch(IOException ex)

   {

     ex.printStackTrace();

   }

   System.exit(1);

  }

 }

public static void main(String[] args)

 {

   Server server = new Server();

  server.init();

 }

}

 

public class ServerThread extends Thread

{

  private Socket socket;

  BufferedReader br = null;

  PrintStream ps = null;

  public ServerThread(Socket socket)

 {

   this.socket = socket;

 }

 public void run()

 {

   try

   {

    br = new BufferedReader(new InputSteamReader(socket.getInputStream()));

    ps = new PrintStream(socket.getOutputStream());

   String line = null;

   while((line = br.readLine()) != null)

  {

    if(line.startsWith(YeekuProtocol.USER_ROUND) && line.endsWith(YeekuProtocol.USER_ROUND))

    {

       String userName = getRealMsg(line);

     if(Server.clients.containsKey(userName))

     {

      System.out.println("重复");

       ps.println(YeekuPrtocol.NAME_REP);

      }

    else

    {

     System.out.println("成功");

     ps.println(YeekuProtocol.LOGIN_SUCCESS);

    server.clients.put(userName,ps);

    }

    }

   else  if(line.startsWith(YeekuProtocol.PRIVATE_ROUND)&&line.endsWith(YeekuProtocol.PRIVATE_ROUND))

   {

     String userAndMsg = getRealMsg(line);

     String user = userAndMsg.split(YeekuProtocol.SPLIT_SIGN)[0];

     String msg = userAndMsg.split(YeekuProtocol.SPLIT_SIGN)[1];

     Server.clients.get(user).println(Server.clients.getKeyByValue(ps)+"悄悄地对你说"+msg);

   

   }

  else

   {

    String msg = getRealMsg(line);

    for(PrintStream clientPs :Server.clients.valueSet())

     {

      clientPs.println(Server.clients.getKeyByValue(ps)+"说"+msg);

    }

   }

  }

   }

catch(IOException e)

{

  Server.clients.removeByValue(ps);

   System.out.println(Server.clients.size());

  try

  {

    if(br !=null)

    {

     br.close();

    }

   if(ps != null)

  {

    ps.close();

  }

  if(socket !=null)

  {

   socket.close();

  }

  }

  catch(IOException ex)

  {

   ex.printStackTrace();

  }

}

 }

public String getRealMsg(String line)

   return line.substring(YeekuProtocol.PROTOCOL_LEN,line.length()-YeekuProtocol.PROTOCOL_LEN);

}

 

}

 

public class Client

{

  private static final int SERVER_PORT = 30000;

  private Socket socket;

  private PrintStream ps;

  private BufferedReader brServer;

  private BufferedReader keyIn;

  public void init()

 {

  try

  {

   keyIn = new BufferedReader(new InputStreamReader(System.in));

   socket = new Socket("127.0.0.1",SERVER_PORT);

   ps = new PrintStream(socket.getOutputStream);

   brServer = new BufferedReader(new InputStreamReader(socket.getInputStream()));

   String tip = "";

   while(true)

   {

     String userName = JOptionPane.showInputDialog(tip+"输入用户名");

     ps.println(YeekuProtocol.USER_ROUND+userName+YeekuProtocol.USER_ROUND);

     String result = brServer.readLine();

     if(result.equals(YeekuProtocol.NAME_REP))

     {

        tip = "用户名重复!请重新";

        continue;

     }

     if(result.equals(YeekuProtocol.LOGIN_SUCCESS))

     {

        break;

     }

   

   }

  

  }

 catch(UnknownHostException ex)

  {

     System.out.println("找不到远程服务器,请确定服务器已经启动");

     closeRs();

     System.exit();

  }

  catch(IOException ex)

  {

    System.out.println("网络异常!请重新登录");

    closeRs();

    System.exit(1);

  }

 new ClientThread(brServer).start();

 

 }

private void readAndSend()

{

  try

 {

   String line = null;

   while((line = keyIn.readLine()) != null)

   {

      if(line.indexOf(":") > 0 && line.startsWith("//"))

      {

        line = line.substring(2);

        ps.println(YeekuProtocol.PRIVATE_ROUND + line.split(":")[0]+YeekuProtocol.SPLIT_SIGN+line.split(":")[1]+YeekuProtocol.PRIVATE_ROUND);

      }

   else

   {

      ps.println(YeekuProtocol.MSG_ROUND + line+YeekuProtocol.MSG_ROUND);

   }

    

   }

 }

 catch(IOException ex)

  {

   System.out.println("网络通信异常!请重新登录!");

   closeRs();

   System.exit(1);

  }

}

 private void closeRs()

{

  try

  {

   if(keyIn != null)

  {

    ps.close();

  }

  if(brServer !=null)

  {

    ps.close();

  }

 if(ps != null)

 {

   ps.close();

 }

 if(socket !=null )

 {

   keyIn.close();

 }

  }

 catch(IOException ex)

{

   ex.printStackTrace();

 }

}

public static void main(String[] args)

{

  Client client = new Client();

  client.init();

   client.readAndSend();

}

}

 

public  class  ClientThread extends Thread

{

   BufferedReader br = null;

   public ClientThread(BufferedReader br)

   {

      this.br = br;

  }

  public void run()

 {

   try

  {

     String line = null;

    while((line = br.readLine()) != null)

    {

      System.out.println(line);

      /*
     本例仅打印了从服务器端读到的内容。实际上,此处的情况可以更复杂:
     如果我们希望客户端能看到聊天室的用户列表,则可以让服务器在
     每次有用户登陆、用户退出时,将所有用户列表信息都向客户端发送一遍。
     为了区分服务器发送的是聊天信息,还是用户列表,服务器也应该
     在要发送的信息前、后都添加一定的协议字符串,客户端此处则根据协议
     字符串的不同而进行不同的处理!
     更复杂的情况:
     如果两端进行游戏,则还有可能发送游戏信息,例如两端进行五子棋游戏,
     则还需要发送下棋坐标信息等,服务器同样在这些下棋坐标信息前、后
     添加协议字符串后再发送,客户端就可以根据该信息知道对手的下棋坐标。
     */
   }
  }
  catch (IOException ex)
  {
   ex.printStackTrace();
  }
  //使用finally块来关闭该线程对应的输入流
  finally
  {
   try
   {
    if (br != null)
    {
     br.close();
    }
   }
   catch (IOException ex)
   {
    ex.printStackTrace();
   }
  }

   }

   }

 

 

半关闭

public class Server

{

   public static void main(String[] args) throws Exception

  {

    ServerSocket  ss = new ServerSocket(30000);

    Socket socket = ss.accept();

    PrintStream ps = new PrintStream(socket.getOutputStream);

    ps.println("服务器的第一行数据");

    ps.println("服务器的第二行数据");

    socket.shutdownOutput();

    System.out.println(socket.isClosed());

    Scanner scan = new Scanner(socket.getInputStream());

    if(scan.hasNextLine())

    {

      System.out.println(scan.nextLine());

    }

    scan.close();

    socket.close();

    ss.close();

  

  }

 

}

抱歉!评论已关闭.