socket入门教程
Server.cs 服务端程序
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using System.Net;
using System.Net.Sockets; namespace SocketTest
{
public partial class Server : Form
{
Thread serverThread; //服务端线程
Thread clientThread; //客户端线程
Socket serverSocket; //服务端socket
Socket clientSocket; //客户端socket public Server()
{
InitializeComponent();
} private void ServerStart()
{
//创建IPEndPoint实例
IPEndPoint ipep = new IPEndPoint(IPAddress.Any, );
//创建一个套接字
serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
//将所创建的套接字与IPEndPoint绑定
serverSocket.Bind(ipep);
//设置套接字为收听模式
serverSocket.Listen(); /**
* 通过serverSocket.Accept()来接收客户Socket的连接请求,
* 在这里用循环可以实现该线程实时侦听,而不是只侦听一次。
* 当程序运行serverSocket.Accept()时,会等待,直到有客户端Socket发起连接请求时,
* 获取该客户Socket,如上面的clientSocket。在这里我用多线程来实现与多个客户端Socket的连接和通信,
* 一旦接收到一个连接后,就新建一个线程,执行ReceiveData功能来实现信息的发送和接收。
*/
while (true)
{
try
{
//在套接字上接收接入的连接
clientSocket = serverSocket.Accept();
clientThread = new Thread(new ThreadStart(ReceiveData));
clientThread.Start();
}
catch (Exception ex)
{
MessageBox.Show("listening Error: " + ex.Message);
}
}
} /**
* 通过IPEndPoint clientep = (IPEndPoint)s.RemoteEndPoint;
* 我们可以获取连接上的远程主机的端口和IP地址,如果想查询该主机的其它属性如主机名等,
* 可用于上一篇讲的Dns.GetHostByAddress(string ipAddress)来返回一个IPHostEntry对象,就可以得到。
* 另外我们要注意的是,通过Socket发送信息,必须要先把发送的信息转化成二进字进行传输,
* 收到信息后也要把收到的二进字信息转化成字符形式,
* 这里可以通过Encoding.ASCII.GetBytes(welcome);和Encoding.ASCII.GetString(buffer).Substring(0, bufLen);来实现。
* 以上就是服务端Socket侦听模式的实现,只要有远程客户端Socket连接上后,就可以轻松的发送信息和接收信息了。
* 下面我们来看看客户端Socket是怎么连接上服务器的。
**/
private void ReceiveData()
{
bool keepalive = true;
Socket s = clientSocket;
Byte[] buffer = new Byte[];
//根据收听到的客户端套接字向客户端发送信息
IPEndPoint clientep = (IPEndPoint)s.RemoteEndPoint;
this.Invoke(new MethodInvoker(() =>
{
lstServer.Items.Add("Client:" + clientep.Address + "(" + clientep.Port + ")");
}));
string welcome = "Welcome to my test sever ";
byte[] data = new byte[];
data = Encoding.ASCII.GetBytes(welcome);
s.Send(data, data.Length, SocketFlags.None);
while (keepalive)
{
//在套接字上接收客户端发送的信息
int bufLen = ;
try
{
bufLen = s.Available;
s.Receive(buffer, , bufLen, SocketFlags.None);
if (bufLen == )
continue;
}
catch (Exception ex)
{
MessageBox.Show("Receive Error:" + ex.Message);
return;
}
clientep = (IPEndPoint)s.RemoteEndPoint;
string clientcommand = System.Text.Encoding.ASCII.GetString(buffer).Substring(, bufLen);
this.Invoke(new MethodInvoker(() =>
{
lstServer.Items.Add(clientcommand + "(" + clientep.Address + ":" + clientep.Port + ")");
}));
}
} private void btnOpen_Click(object sender, EventArgs e)
{
serverThread = new Thread(new ThreadStart(ServerStart));
serverThread.Start();
lstServer.Items.Add("Server Start .....");
}
}
}
Client.cs(客户端程序)
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Net;
using System.Net.Sockets;
using System.Threading; namespace Client
{
public partial class Client : Form
{
Socket clientSocket;
Thread clientThread; public Client()
{
InitializeComponent();
} /**
* 客户端Socket连接相对来说比较简单了,另外说明一下,在执行客户端连接前,服务端Socket侦听必须先启动,
* 不然会提示服务器拒绝连接的信息。
* 客户端的发送信息和接收信息跟服务器的接收发送是一样的,只不过一个是侦听模式而另一个是连接模式。
* 另外提一下,这里服务端开启侦听服务、客户端连接服务端都采用线程方式来实现,这样服务端能够跟多个客户端同时通信,不用等候,
* 当然还有另外一种方式可以实现那就是异步socket.
*/
private void ConnectToServer()
{
byte[] data = new byte[];
//创建一个套接字
IPEndPoint ipep = new IPEndPoint(IPAddress.Parse("127.0.0.1"), );
clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
//将套接字与远程服务器地址相连
try
{
clientSocket.Connect(ipep);
}
catch (SocketException ex)
{
MessageBox.Show("connect error: " + ex.Message);
return;
}
while (true)
{
//接收服务器信息
int bufLen = ;
try
{
bufLen = clientSocket.Available;
clientSocket.Receive(data, , bufLen, SocketFlags.None);
if (bufLen == )
{
continue;
}
}
catch (Exception ex)
{
MessageBox.Show("Receive Error:" + ex.Message);
return;
}
string clientcommand = System.Text.Encoding.ASCII.GetString(data).Substring(, bufLen);
this.Invoke(new MethodInvoker(() =>
{
lstClient.Items.Add(clientcommand);
}));
//clientSocket.Shutdown(SocketShutdown.Both);
//clientSocket.Close();
}
} private void button1_Click(object sender, EventArgs e)
{
clientThread = new Thread(new ThreadStart(ConnectToServer));
clientThread.Start();
} private void btnSend_Click(object sender, EventArgs e)
{
//向服务器发送信息
byte[] data = new byte[];
data = Encoding.ASCII.GetBytes(txtClient.Text);
clientSocket.Send(data, data.Length, SocketFlags.None);
}
}
}
socket入门教程的更多相关文章
- 最基础的Python的socket编程入门教程
最基础的Python的socket编程入门教程 本文介绍使用Python进行Socket网络编程,假设读者已经具备了基本的网络编程知识和Python的基本语法知识,本文中的代码如果没有说明则都是运行在 ...
- kafka入门教程链接
http://www.aboutyun.com/forum.php?mod=viewthread&tid=12882 经典入门教程 1.Kafka独特设计在什么地方?2.Kafka如何搭建及创 ...
- 超强、超详细Redis数据库入门教程
这篇文章主要介绍了超强.超详细Redis入门教程,本文详细介绍了Redis数据库各个方面的知识,需要的朋友可以参考下 [本教程目录] 1.redis是什么2.redis的作者何许人也3.谁在使用red ...
- 超强、超详细Redis数据库入门教程(转载)
这篇文章主要介绍了超强.超详细Redis入门教程,本文详细介绍了Redis数据库各个方面的知识,需要的朋友可以参考下 [本教程目录] 1.redis是什么 2.redis的作者何许人也 3.谁在使 ...
- Webpack 入门教程
Webpack 是一个前端资源加载/打包工具.它将根据模块的依赖关系进行静态分析,然后将这些模块按照指定的规则生成对应的静态资源. 本章节基于 Webpack3.0 测试通过. 从图中我们可以看出,W ...
- Docker(一):Docker入门教程
如今Docker的使用已经非常普遍,特别在一线互联网公司.使用Docker技术可以帮助企业快速水平扩展服务,从而到达弹性部署业务的能力.在云服务概念兴起之后,Docker的使用场景和范围进一步发展,如 ...
- 【转帖】Systemd 入门教程:命令篇
Systemd 入门教程:命令篇 Copy From http://www.ruanyifeng.com/blog/2016/03/systemd-tutorial-commands.html 感觉 ...
- Netty入门教程——认识Netty
什么是Netty? Netty 是一个利用 Java 的高级网络的能力,隐藏其背后的复杂性而提供一个易于使用的 API 的客户端/服务器框架. Netty 是一个广泛使用的 Java 网络编程框架(N ...
- 超强、超详细Redis入门教程【转】
这篇文章主要介绍了超强.超详细Redis入门教程,本文详细介绍了Redis数据库各个方面的知识,需要的朋友可以参考下 [本教程目录] 1.redis是什么2.redis的作者何许人也3.谁在使用red ...
随机推荐
- 蓝桥java 入门训练 Fibonacci数列
import java.util.Scanner; public class Main{ public static void main(String[] args) { int maxn=10000 ...
- Source Tree 簡介
Table of Contents 1. 什麼是 Source Tree ? 1.1. 下載 1.2. SourceTree 介面簡介 1.3. git 指令/狀態圖 2. SourceTrees 超 ...
- BUPT复试专题—List(2015)
题目描述 在该LIST上实现3种操作 1.append x在该LIST末尾添加x,x是32位整数 2.pop删除该LIST末尾的数 3.find i寻找第i个数,若i为负数表示寻找倒数第i个数,例如i ...
- jmeter - DBC Request之Query Type
工作中遇到这样一个问题: 需要准备10W条测试数据,利用jmeter中的JDBC Request向数据库中批量插入这些数据(只要主键不重复就可以,利用函数助手中的Random将主键的ID末尾五位数随机 ...
- Ikki's Story IV - Panda's Trick (poj 3207 2-SAT)
Language: Default Ikki's Story IV - Panda's Trick Time Limit: 1000MS Memory Limit: 131072K Total S ...
- 父节点parentNode
<!DOCTYPE HTML> <html> <head> <meta http-equiv="Content-Type" content ...
- 【手势交互】4. Kinect for XBox
"You are the Controller",Kinect for Xbox的广告词.明白说明了Kinect体感的交互方式.作为一款集成了诸多先进视觉技术的自然交互设备,Kin ...
- Intel MIC
http://en.wikipedia.org/wiki/Intel_MIC Intel MIC From Wikipedia, the free encyclopedia Intel Man ...
- Vue 建立工程
npm install -g vue npm install -g vue-cli vue init webpack my-project cd my-project npm isntall npm ...
- FPGA 功耗结构设计
1 相对于ASIC.FPGA是耗电器件,不适合超低功耗设计技术. 2 在CMOS技术中电路的动态功耗与门和金属引线的充放电有关,电容消耗电流的一般方程为 I=V* C*f V 是电压.对于FPGA来说 ...