代码改变世界

Socket网络编程(二):面向连接

2010-09-27 16:10  czyhsl  阅读(553)  评论(0编辑  收藏  举报

Socket网络编程(一)中对Socket有了一个简单的了解,在同步、异步通信中该如何一步步去实现以及使用哪些方法也有了一个大概的认识。Socket原理:服务器端有一个进程(或者多个进程)在指定端口等待客户来连接,服务程序等待客户的连接信息,一旦连接上之后,就可以按设计的数据交换方法和格式进行数据传输。客户端在需要的时刻发出向服务端的连接请求。

首先来梳理一下服务端侦听的步骤:

1)创建IPEndPoint实例,用于Socket侦听时绑定

2)创建套接字的实例

3)将所创建的套接字与IpEndPoint绑定

4)设置套接字的模式

5)在套接字上接收接入的连接

6)在套接字上接收客户端发送的消息和向客户端发送消息

 

下面是客户端连接服务器的步骤:

1)创建IpEndPoint实例和套接字

2)将套接字连接到远程服务器

3)接收消息

4)发送消息

 

以上是Socket应用的基本步骤,知道这个,起码我们可以有一个明确的方向。就像框架一样,只需要”拿来主义“。接下面分享下服务端、客户端的代码:

 

服务端:

代码
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using System.Net;
using System.Net.Sockets;

namespace Server
{
public partial class Server : Form
{
Thread serverThread;
Thread clientThread;
Socket serverSocket;
Socket clientSocket;

public Server()
{
InitializeComponent();
}

private void ServerStart()
{
//创建IPEndPoint实例,用于Socket侦听时绑定
IPEndPoint ipep = new IPEndPoint(IPAddress.Any, 6001);
//创建套接字实例
serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
serverSocket.Bind(ipep);
//将所创建的套接字与IPEndPoint绑定
serverSocket.Listen(10); //设置套接字为收听模式

//在套接字上接收接入的连接
while(true)
{
try
{
clientSocket
= serverSocket.Accept();
clientThread
= new Thread(new ThreadStart(ReceiveData));
clientThread.Start();
}
catch (Exception ex)
{
MessageBox.Show(
"Listening Error:" + ex.Message);
}
}
}

//在套接字上接收客户端发送的消息和向客户端发送消息
private void ReceiveData()
{
bool keepAlive = true;
Socket s
= clientSocket;
Byte[] buffer
= new Byte[1024];

IPEndPoint clientip
= (IPEndPoint)s.RemoteEndPoint;
lstServer.Items.Add(
"Client:" + clientip.Address + "(" + clientip.Port + ")");
string welcome = "Welcome to my test server";
byte[] data = new byte[1024];
data
= Encoding.ASCII.GetBytes(welcome);
s.Send(data, data.Length, SocketFlags.None);

while(keepAlive)
{
int bufLen = 0;
try
{
bufLen
= s.Available;
s.Receive(buffer,
0, bufLen, SocketFlags.None);
if (bufLen == 0)
continue;
}
catch (Exception ex)
{
MessageBox.Show(
"Receive Error:" + ex.Message);
return;
}
clientip
= (IPEndPoint)s.RemoteEndPoint;
string clientCommand = Encoding.ASCII.GetString(buffer).Substring(0, bufLen);
lstServer.Items.Add(clientCommand
+ "(" + clientip.Address + ":" + clientip.Port + ")");
}
}

private void button1_Click(object sender, EventArgs e)
{
serverThread
= new Thread(new ThreadStart(ServerStart));
serverThread.Start();
lstServer.Items.Add(
"Server Start...");
}
}
}


客户端:

代码
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
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();
}

private void ConnectToServer()
{
byte[] data = new byte[1024];

IPEndPoint ipep
= new IPEndPoint(IPAddress.Parse("127.0.0.1"), 6001);
clientSocket
= new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

try
{
//将套接字与远程服务器相连
clientSocket.Connect(ipep);
}
catch (Exception ex)
{
MessageBox.Show(
"Connect Error: " + ex.Message);
return;
}

while(true)
{
//接收服务器信息
int bufLen = 0;

try
{
bufLen
= clientSocket.Available;
clientSocket.Receive(data,
0, bufLen, SocketFlags.None);
if (bufLen == 0)
continue;
}
catch (Exception ex)
{
MessageBox.Show(
"Receive Error:" + ex.Message);
return;
}

string clientCommand = Encoding.ASCII.GetString(data).Substring(0, bufLen);
lstClient.Items.Add(clientCommand);
}
}

private void btnConnect_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[1024];
data
= Encoding.ASCII.GetBytes(txtClient.Text);
clientSocket.Send(data, data.Length, SocketFlags.None);
}
}
}

 

这两段代码看似不多,然而却对我们入门至关重要!值得好好去研究一下...