网络通讯Socket

网络

在物理网络的基础上,建立抽象的连接

win + r, 输入 cmd

输入命令:

ipconfig

如果ping不通,要关闭防火墙

开始---搜索防火墙

Socket 通信

Socket - 插头

Socket - 网络套接字

通过 ip 地址,两台主机可以互相找到对象

在两台主机上,各选择一个端口号

端口是独占的,0到1024是一些常见服务的默认端口---http 80--https 443--ftp 21...5万以后,是系统保留端口用,来自动分配

我们选择端口要选择 1024到5万之间的端口号

服务器端

被动等待客户端发起连接

ServerSocket 在服务器端,选择一个端口号, 在指定端口上等待客户端发起连接

ServerSocket ss = new ServerSocket(8000);

等待客户端发起连接,建立连接通道,并返回连接通道的服务器端插头对象

Socket s = ss.accept();

客户端

主动去连接服务器

Socket s = new Socket(ip, port);

取出双向的流

InputStream in = s.getInputStream();

OutputStream out = s.getOutputStream();

超时

socket.setSoTimeout(毫秒值)

设置接收数据,等待超时时长,超时会出现 SocketTimeoutException

实例:

package demo;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;

public class Server1 {

public static void main(String[] args) throws Exception {
    ServerSocket ss = new ServerSocket(8000);
    System.out.println(
     "服务已经在 8000 端口上启动");
    //暂停等待客户端发起连接
    System.out.println("等待客户端连接");
    Socket s = ss.accept();
    System.out.println("客户端已连接");
    //从插头对象,获取输入流和输出流
    InputStream in = s.getInputStream();
    OutputStream out = s.getOutputStream();
    /*
     * 通信协议,通信流程,数据格式
     *
     *     服务器端:
     *       1. 接收 "hello"
     *       2. 发送 "world"
     */
    for (int i = 0; i < 5; i++) {
        char c = (char) in.read();
        System.out.print(c);
    }
    out.write("world".getBytes());
    out.flush(); //刷出内存缓存
    s.close();//断开连接
    ss.close();//停止服务,释放端口
}
}

Client

package demo;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;

public class Client1 {
public static void main(String[] args) throws Exception {
    Socket s = new Socket("旁边同学ip", 8000);
    InputStream in = s.getInputStream();
    OutputStream out = s.getOutputStream();
    /* 客户端:
     *    1. 发送 "hello"
     *    2. 接收 "world"
     */
    out.write("hello".getBytes());
    out.flush(); //刷出内存缓存
    for (int i = 0; i < 5; i++) {
        char c = (char) in.read();
        System.out.print(c);
    }
    s.close();
}
}

阻塞操作

ss.accept()

暂停,等待客户端发起连接

in.read()

对方不发送数据,暂停,死等数据

服务器端的线程模型

回声

客户端发送到服务器的数据,原封不动的发回客户端

EchoServer

package demo;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;

public class EchoServer {
public void launch() {
    new Thread() {
        @Override
        public void run() {
           try {
              ServerSocket ss = new ServerSocket(8000);
              System.out.println("服务已在 8000 端口上启动");
              while(true) {
                 System.out.println("等待下一个客户端连接");
                 Socket s = ss.accept();
                 System.out.println("客户端已连接");
                 TongXinThread t = new TongXinThread(s);
                 t.start();
              }
           } catch (Exception e) {
              System.out.println(
               "无法在 8000 端口上启动服务,或服务已停止");
           }
        }
    }.start();
}
class TongXinThread extends Thread {
    Socket s;
    public TongXinThread(Socket s) {
        this.s = s;
    }
    @Override
    public void run() {
        /*
         * 通信协议,流程和格式
         * UTF-8编码的字符串,
         * 每段字符串末尾添加换行
         *
         * BR--ISR--网络输入流
         * PW--OSW--网络输出流
         */
        try {
           BufferedReader in =
            new BufferedReader(
            new InputStreamReader(
            s.getInputStream(), "UTF-8"));
           PrintWriter out =
            new PrintWriter(
            new OutputStreamWriter(
            s.getOutputStream(),"UTF-8"));
           String line;
           while((line = in.readLine()) != null) {
              out.println(line);
              out.flush();
           }
           //断开
        } catch (Exception e) {
           //断开
        }
        System.out.println("一个客户端端已断开");
    }
}

public static void main(String[] args) {

    EchoServer s = new EchoServer();

    s.launch();

}

}

EchoClient

package demo;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.net.Socket;
import java.util.Scanner;

public class EchoClient {
public static void main(String[] args) throws Exception {
    Socket s = new Socket("找一个人启动服务器", 8000);
    BufferedReader in =
     new BufferedReader(
     new InputStreamReader(
     s.getInputStream(), "UTF-8"));
    PrintWriter out =
     new PrintWriter(
     new OutputStreamWriter(
     s.getOutputStream(),"UTF-8"));
    while(true) {
        System.out.print("输入:");
        String str = new Scanner(System.in).nextLine();
        out.println(str);
        out.flush();
        String echo = in.readLine();
        System.out.println("回声:"+echo);
        System.out.println("-----------------");
    }
}
}

聊天室

ChatServer

package demo;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;

public class ChatServer {
private ArrayList<TongXinThread> list =
        new ArrayList<>();
public void launch() {
    //启动服务线程
    new Thread() {
        @Override
        public void run() {
           try {
              ServerSocket ss = new ServerSocket(8000);
              System.out.println("聊天室服务器已启动");
              while(true) {
                 Socket s = ss.accept();
                 TongXinThread t =
                  new TongXinThread(s);
                 t.start();
              }
           } catch (Exception e) {
              System.out.println(
               "服务无法在 8000 端口上启动,或服务已经停止");
           }
        }
    }.start();
}

class TongXinThread extends Thread {
    Socket s;
    BufferedReader in;
    PrintWriter out;
    private String name;
    public TongXinThread(Socket s) {
        this.s = s;
    }
    public void send(String msg) {
        out.println(msg);
        out.flush();
    }
    public void sendAll(String msg) {
        synchronized (list) {
           for (TongXinThread t : list) {
              t.send(msg);
           }
        }
    }
    @Override
    public void run() {
        try {
           //UTF-8, 换行
           in = new BufferedReader(new InputStreamReader(s.getInputStream(), "UTF-8"));
           out = new PrintWriter(new OutputStreamWriter(s.getOutputStream(),"UTF-8"));
           //接收客户端的昵称
           this.name = in.readLine();
           //把当前通信线程实例,加入集合
           synchronized (list) {
              list.add(this);
           }
           //发送欢迎信息
           send("欢迎进入激情聊天室");
           //群发上线消息
           sendAll(name+"进入了聊天室,在线人数:"+list.size());
           String line;
           while((line = in.readLine()) != null) {
              sendAll(name+"说:"+line);
           }
           //断开
        } catch (Exception e) {
           //断开
        }
        //删除当前通信线程实例
        synchronized (list) {
           list.remove(this);
        }
        //群发离线消息
        sendAll(name+"离开了聊天室,在线人数:"+list.size());
    }
}

public static void main(String[] args) {

    ChatServer s = new ChatServer();

    s.launch();

}

}

ChatClient

package demo;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.LinkedList;
import java.util.Scanner;

public class ChatClient {
private Socket s;
private BufferedReader in;
private PrintWriter out;
private String name;
private LinkedList<String> list = new LinkedList<>();
private boolean flag; //开关

public void launch() {
    try {
        s = new Socket("192.168.21.61", 8000);
        in = new BufferedReader(new InputStreamReader(s.getInputStream(), "UTF-8"));
        out = new PrintWriter(new OutputStreamWriter(s.getOutputStream(),"UTF-8"));
        //昵称
        System.out.print("起一个昵称: ");
        name = new Scanner(System.in).nextLine();
        out.println(name);
        out.flush();
        //接收线程
        new Thread() {
           @Override
           public void run() {
              receive();
           }
        }.start();
        //输入线程
        new Thread() {
          @Override
           public void run() {
              input();
           }
        }.start();
        //打印线程
        new Thread() {
           @Override
           public void run() {
              print();
           }
        }.start();
    } catch (Exception e) {
        System.out.println("无法连接聊天室服务器");
        e.printStackTrace();
    }
}
protected void print() {
    while(true) {
        synchronized (list) {
           while (list.isEmpty() || flag) {
              try {
                 list.wait();
            } catch (InterruptedException e) {
           }
          }
           String msg = list.removeFirst();
           System.out.println(msg);
        }
    }
}
protected void input() {
    System.out.println("按回车输入聊天内容");
    while(true) {
        new Scanner(System.in).nextLine();
        flag = true;//打开开关
        System.out.print("输入聊天内容:");
        String s = new Scanner(System.in).nextLine();
        out.println(s);
        out.flush();
        flag = false;//关闭开关
        //通知打印线程可以继续打印
        synchronized (list) {
        list.notify();
        }
    }
}
protected void receive() {
    try {
        String line;
        while((line = in.readLine()) != null) {
           synchronized (list) {
              list.add(line);
              //通知打印线程已经有数据可以打印了
              list.notify();
          }
        }
    } catch (Exception e) {
    }
    System.out.println("已经与服务器断开连接");
}
public static void main(String[] args) {
    ChatClient c = new ChatClient();
    c.launch();
}
}

原文地址:https://www.cnblogs.com/yunianzeng/p/12109804.html

时间: 2024-08-11 09:48:40

网络通讯Socket的相关文章

[转] C#.Net Socket网络通讯编程总结

1.理解socket1).Socket接口是TCP/IP网络的应用程序接口(API).Socket接口定义了许多函数和例程,程序员可以用它们来开发TCP/IP网络应用程序.Socket可以看成是网络通信上的一个端点,也就是说,网络通信包括两台主机或两个进程,通过网络传递它们之间的数据.为了进行网络通信,程序在网络对话的每一端都需要一个Socket. 2).TCP/IP传输层使用协议端口将数据传送给一台主机的特定应用程序,从网络的观点看,协议端口是一个应用程序的进程地址.当传输层模块的网络软件模块

C#.NET通过Socket实现平行主机之间网络通讯(含图片传输的Demo演示)

在程序设计中,涉及数据存储和数据交换的时候,不管是B/S还是C/S模式,都有这样一个概念:数据库服务器.这要求一台性能和配置都比较好的主机作为服务器,以满足数目众多的客户端进行频繁访问.但是对于一些数据交换的要求不主同,而且涉及到的通讯个体数目不多,如果还采用“一主机多客户机”的模式,便要求一台硬件配置良好而且软件上安装了相关数据服务软件,这样会造成硬件和软件上的很多不必要的成本,这时Socket在点对点的平行对象之间的网络通讯的优势就就发挥出来了. 其实对于Socket通讯来说,服务器和客户端

项目日志之基于Java socket的网络通讯

Java API网络类包中的Socket类是网络上运行的两个程序间双向通信的一端,它既可以接受请求,也可以发送请求,利用它可以较为方便的编写网络上数据的传递.我们打算通过Java中基于Socket的网络编程实现一个简单的网络通信程序.这就是我们团队项目(开发一款简单的通讯软件,其基本功能是实现一对一的网络信息通讯,并努力向一对多和多对多靠近)的主要内容. 一.Java socket通信开发原理(查阅资料): 服务器使用ServerSocket监听指定的端口,端口可以随意指定(由于1024以下的端

Python 网络编程socket大全 用途---用于客户端和服务器端之间相互通讯

本章目录 一.什么是socket 二.为什么需要socket 三.socket的发展 四.python中的socket 五.基于TCP的socket 六.基于UDP的socket 六. 粘包问题详解 七.粘包的解决方案 八.socketserver实现并发通讯 **引入:为什么一定要先学习网络协议?** 之所以学习网络编程就是为了让我们的程序能够利用网络来传输数据,开发出C/S构架的应用程序 而网络的核心,就是协议,没有协议就没有互联网,我们要开发出C/S结构程序则必须遵循这些协议的标准! `就

Android网络通讯简介

网络通信应该包含三部分的内容:发送方.接收方.协议栈.发送方和接收方是参与通信的主体,协议栈是发送方和接收方进行通信的契约.按照服务类型,网络通信可分为面向连接和无连接的方式.面向连接是在通信前建立通信链路,而通信结束后释放该链路.无连接的方式则不需要在通信前建立通信连接,这种方式不保证传输的质量. Android提供了多种网络通信的方式,如Java中提供的网络编程,在Android中都提供了支持.Android中常用的网络编程方式如下: 针对TCP/IP协议的Socket和ServerSock

网络--三种网络通讯方式及Android的网络通讯机制

Android平台有三种网络接口可以使用,他们分别是:java.net.*(标准Java接口).Org.apache接口和Android.net.*(Android网络接口).下面分别介绍这些接口的功能和作用. 1.标准Java接口 java.net.*提供与联网有关的类,包括流.数据包套接字(socket).Internet协议.常见Http处理等.比如:创建URL,以及URLConnection/HttpURLConnection对象.设置链接参数.链接到服务器.向服务器写数据.从服务器读取

网络编程--Socket(套接字)

网络编程 网络编程的目的就是指直接或间接地通过网络协议与其他计算机进行通讯.网络编程中 有两个主要的问题,一个是如何准确的定位网络上一台或多台主机,另一个就是找到主机后 如何可靠高效的进行数据传输.在TCP/IP协议中IP层主要负责网络主机的定位,数据传输的 路由,由IP地址可以唯一地确定Internet上的一台主机.而TCP层则提供面向应用的可靠的 或非可靠的数据传输机制,这是网络编程的主要对象,一般不需要关心IP层是如何处理数据 的. 目前较为流行的网络编程模型是客户机/服务器(C/S)结构

个人第一个开源分布式项目distributeTemplate的实现三 网络通讯netty传输大文件

今天 我将讲讲网络通讯,这里我初始版本 由于采用的事Netty框架  所以 这里讲网络Netty在我们这里是怎么使用的,下周开始添加rpc lucene内容了 实现之后的0.2 0.3版本,后面将会去掉netty依赖 采用原生的NIO2 (aio) 异步非阻塞方式 实现自己网络通讯,也就是说 这部分可能会实现一个简单的但是比netty精简高效的网络框架,后期做出来 可能会单独开一个分支开源出来,netty说白了 就是 事件驱动 以及 NIO 加一些协议 以及 异常 处理,废话不多说了. 我最近

网络通讯之套接字编程

#include<stdio.h> #include<sys/socket.h> #include<netinet/in.h> static char out_ip[15] = "52.0.10.188"; static int out_port = 8888; int main() { char sSendBuf[2049], sRecvBuf[2049]; int connfd = 0, iRet = 0, iSendLen = 0; struc