C# Socket网络编程实例

本文实例讲述了C# Socket网络编程技巧。分享给大家供大家参考。具体分析如下:

客户端要连接服务器:首先要知道服务器的IP地址。而服务器里有很多的应用程序,每一个应用程序对应一个端口号

所以客户端想要与服务器中的某个应用程序进行通信就必须要知道那个应用程序的所在服务器的IP地址,及应用程序所对应的端口号


TCP协议:

安全稳定,一般不会发生数据丢失,但是效率低。利用TCP发生数据一般经过3次握手(所有效率低,自己百度三次握手)


UDP协议:

快速,效率高,但是不稳定,容易发生数据丢失(没有经过三次握手,不管服务器有空没空,信息全往服务器发,所有效率搞,但服务器忙的时候就没办法处理你的数据,容易造成数据丢失,不稳定)

代码如下:

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.Sockets;

using System.Net;

using System.Threading;

namespace Socket通信

{

public partial class Form1 : Form

{

public Form1()

{

InitializeComponent();

this.txtPort.Text = “5000”;

this.txtIp.Text = “192.168.137.1”;

}

private void btnStart_Click(object sender, EventArgs e)

{

//当点击开始监听的时候,在服务器端创建一个负责监听IP地址跟端口号的Socket

Socket socketWatch = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);

//Any:提供一个 IP 地址,指示服务器应侦听所有网络接口上的客户端活动。此字段为只读。

IPAddress ip = IPAddress.Any;

//创建端口号对象;将txtPort.Text控件的值设为服务端的端口号

IPEndPoint point = new IPEndPoint(ip, Convert.ToInt32(txtPort.Text));

//监听

socketWatch.Bind(point);

ShowMsg(“监听成功”);

socketWatch.Listen(10);//连接队列的最大长度 ;即:一个时间点内最大能让几个客户端连接进来,超过长度就进行排队

//等待客户端连接;Accept()这个方法能接收客户端的连接,并为新连接创建一个负责通信的Socket

Thread th = new Thread(Listen); //被线程执行的方法如果有参数的话,参数必须是object类型

Control.CheckForIllegalCrossThreadCalls = false; //因为.net不允许跨线程访问的,所以这里取消跨线程的检查。.net不检查是否有跨线程访问了,所有就不会报: “从不是创建控件“txtLog”的线程访问它” 这个错误了,从而实现了跨线程访问

th.IsBackground = true; //将th这个线程设为后台线程。

//Start(object parameter); parameter:一个对象,包含线程执行的方法要使用的数据,即线程执行Listen方法,Listen的参数

th.Start(socketWatch);  //这个括号里的参数其实是Listen()方法的参数。因为Thread th = new Thread(Listen)这个括号里只能写方法名(函数名) 但是Listen()方法是有参数的,所有就要用Start()方法将它的参数添加进来

}

/// <summary>

/// 等待客户端连接,如果监控到有客户端连接进来就创建一个与之通信的Socket

/// </summary>

/// <param name=”o”></param>

void Listen(object o) //这里为什么不直接传递Socket类型的参数呢? 原因是:被线程执行的方法如果有参数的话,参数必须是object类型

{

Socket socketWatch = o as Socket;

while (true) //为什么这里要有个while循环?因为当一个人连接进来的时候创建了与之通信的Socket后就程序就会往下执行了,就不会再回来为第二个人的连接创建负责通信的Socket了。(应该是每个人(每个客户端)创建一个与之通信的Socket)所以要写在循环里。

{

//等待客户端连接;Accept()这个方法能接收客户端的连接,并为新连接创建一个负责通信的Socket

Socket socketSend = socketWatch.Accept();

dic.Add(socketSend.RemoteEndPoint.ToString(), socketSend); //(根据客户端的IP地址和端口号找负责通信的Socket,每个客户端对应一个负责通信的Socket),ip地址及端口号作为键,将负责通信的Socket作为值填充到dic键值对中。

//我们通过负责通信的这个socketSend对象的一个RemoteEndPoint属性,能够拿到远程连过来的客户端的Ip地址跟端口号

ShowMsg(socketSend.RemoteEndPoint.ToString() + “:” + “连接成功”);//效果:192.168.1.32:连接成功

comboBox1.Items.Add(socketSend.RemoteEndPoint.ToString()); //将连接过来的每个客户端都添加到combBox控件中。

//客户端连接成功后,服务器应该接收客户端发来的消息。

Thread getdata = new Thread(GetData);

getdata.IsBackground = true;

getdata.Start(socketSend);

}

}

Dictionary<string, Socket> dic = new Dictionary<string, Socket>();

/// <summary>

/// 不停的接收客户端发送过来的消息

/// </summary>

/// <param name=”o”></param>

void GetData(object o)

{

while (true)

{

Socket socketSend = o as Socket;

//将客户端发过来的数据先放到一个字节数组里面去

byte[] buffer = new byte[1024 * 1024 * 2]; //创建一个字节数组,字节数组的长度为2M

//实际接收到的有效字节数; (利用Receive方法接收客户端传过来的数据,然后把数据保存到buffer字节数组中,返回一个接收到的数据的长度)

int r = socketSend.Receive(buffer);

if (r == 0) //如果接收到的有效字节数为0 说明客户端已经关闭了。这时候就跳出循环了。

{

//只有客户端给用户发消息,不可能是发0个长度的字节。即便发空消息,空消息也是有过个长度的。所有接收到的有效字节长度为0就代表客户端已经关闭了

break;

}

//将buffer这个字节数组里面的数据按照UTF8的编码,解码成我们能够读懂的的string类型,因为buffer这个数组的实际存储数据的长度是r个 ,所以从索引为0的字节开始解码,总共解码r个字节长度。

string str = Encoding.UTF8.GetString(buffer, 0, r);

ShowMsg(socketSend.RemoteEndPoint.ToString() + “:” + str);

}

}

private void ShowMsg(string str)

{

txtLog.AppendText(str + “\r\n”); //将str这个字符串添加到txtLog这个文本框中。

}

/// <summary>

/// 服务端给客户端发信息

/// </summary>

/// <param name=”sender”></param>

/// <param name=”e”></param>

private void btnSend_Click_1(object sender, EventArgs e)

{

if (comboBox1.SelectedItem == null) //如果comboBox控件没有选中值。就提示用户选择客户端

{

MessageBox.Show(“请选择客户端”);

return;

}

string str = txtMes.Text; //获取用户输入的内容 (服务端要给客户端发的信息)

byte[] strByte = Encoding.Default.GetBytes(str); //将信息转换成二进制字节数组

string getIp = comboBox1.SelectedItem as string; //comboBox存储的是客户端的(ip+端口号)

Socket socketSend = dic[getIp] as Socket; //根据这个(ip及端口号)去dic键值对中找对应 赋值与客户端通信的Socket【每个客户端都有一个负责与之通信的Socket】

socketSend.Send(strByte); //将信息发送到客户端

}

}

}

开打开始命令  cmd   telnet 10.18.16.46 5000    即telnet 服务器ip地址  绑定的端口号

希望本文所述对大家的C#程序设计有所帮助。

除声明外,跑步客文章均为原创,转载请以链接形式标明本文地址
  C# Socket网络编程实例

本文地址:  http://www.paobuke.com/develop/c-develop/pbk23169.html

相关内容

VS2012 程序打包部署图文详解

解析C#设计模式编程中备忘录模式的运用

C#通过流写入数据到文件的方法

C#、ASP.NET通用扩展工具类之TypeParse


C#中数组段用法实例分析

C#???ú×a·¢ó?·¨?ê?a

C#特性-对象集合初始化器介绍

DevExpress实现为TextEdit设置水印文字的方法

时间: 2024-09-30 00:02:18

C# Socket网络编程实例的相关文章

C语言Socket网络编程实例

转自:http://www.cnblogs.com/huxc/p/4272940.html 服务端: #define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <winsock2.h> #pragma comment (lib, "ws2_32.lib") /* TCP服务端 */ int main(void) { int len = 0; WSADATA wd; int ret = 0; SOCKE

Python Socket,How to Create Socket Server? - 网络编程实例

文章出自:Python socket – network programming tutorial by Silver Moon 原创译文,如有版权问题请联系删除. Network programing in Python: Part2: Programing sockets servers. 在所有的通信实例中,都分为Client 和Server. 其中:Client是请求的发起点,Server是使用Socket接收传入的值并且提供返回数据. Server的职能如下: 1>.创建/打开一个so

Java基础篇Socket网络编程中的应用实例

说到java网络通讯章节的内容,刚入门的学员可能会感到比较头疼,应为Socket通信中一定会伴随有IO流的操作,当然对IO流比较熟练的哥们会觉得这是比较好玩的一章,因为一切都在他们的掌握之中,这样操作起来就显得非常得心应手,但是对于IO本来就不是多熟悉的哥们来说就有一定的困难了,在搞清楚IO流操作机制的同时还必须会应用到Socket通信中去,否则会对得到的结果感到非常郁闷和懊恼,下面就和大家一起分享一下自己遇到一点小麻烦后的感触以及给出的解决办法. 要求:客户端通过Socket通信技术上传本地一

Socket网络编程(TCP/IP/端口/类)和实例

Socket网络编程(TCP/IP/端口/类)和实例 原文:C# Socket网络编程精华篇 转自:微冷的雨 我们在讲解Socket编程前,先看几个和Socket编程紧密相关的概念: TCP/IP层次模型 当然这里我们只讨论重要的四层 01,应用层(Application):应用层是个很广泛的概念,有一些基本相同的系统级TCP/IP应用以及应用协议,也有许多的企业应用和互联网应用.http协议在应用层运行. 02,传输层(Tanspot):传输层包括UDP和TCP,UDP几乎不对报文进行检查,而

socket 网络编程快速入门(一)教你编写基于UDP/TCP的服务(客户端)通信

因为UNIX和Win的socket大同小异,为了方便和大众化,这里先介绍Winsock编程. socket 网络编程的难点在入门的时候就是对基本函数的了解和使用,因为这些函数的结构往往比较复杂,参数大部分都是结构体,令人难以记忆和理解. 但是一旦我们知道这些函数包括其参数的具体含义,socket网络编程也就变得不是那么复杂.这里不赘述 具体函数的详细含义,网络上有很多的文章,同时笔者建议大家参考 MSDN,对返回值,参数等会有更好的理解. 以下均为单线程的简单实例,多线程的请关注下一篇文章. (

Linux Socket 网络编程

Linux下的网络编程指的是socket套接字编程,入门比较简单.在学校里学过一些皮毛,平时就是自学玩,没有见识过真正的socket编程大程序,比较遗憾.总感觉每次看的时候都有收获,但是每次看完了之后,过段时间不看,重新拾起这些知识的时候又要从头开始,所以,在这里做个笔记也算是做个模板,以后可以直接从某一个阶段开始接着玩... 1. socket套接字介绍 socket机制其实就是包括socket, bind, listen, connect, accept等函数的方法,其通过指定的函数实现不同

linux下C语言socket网络编程简例

转自:http://blog.csdn.net/kikilizhm/article/details/7858405 这里给出在linux下的简单socket网络编程的实例,使用tcp协议进行通信,服务端进行监听,在收到客户端的连接后,发送数据给客户端:客户端在接受到数据后打印出来,然后关闭.程序里有详细的说明,其中对具体的结构体和函数的实现可以参考其他资料. 程序说明: 这里服务器的端口号和ip地址使用固定的设置,移植时可以根据具体情况更改,可以改写为参数传递更好,这里为了方便,使用固定的. 移

socket编程之三:socket网络编程中的常用函数

这节本来打算先给出常用函数介绍,再给两个代码实例,写着写着发现越来越长,决定把代码放在下一节. 本节内容持续更新...... 1 socket()函数 原型: int socket(int domain, int type, int protocol); 描述: 类似打开一个文件,返回一个socket描述符,唯一标识一个socket,后面相应的操作都是这用这个socket描述符. 参数: domain:协议族,常用的协议族有AF_INET.AF_INET6.AF_LOCAL.AF_ROUTE等:

Socket网络编程--epoll小结

以前使用的用于I/O多路复用为了方便就使用select函数,但select这个函数是有缺陷的.因为它所支持的并发连接数是有限的(一般小于1024),因为用户处理的数组是使用硬编码的.这个最大值为FD_SETSIZE,这是在<sys/select.h>中的一个常量,它说明了最大的描述符数.但是对于大多数应用程序而言,这个数是够用的,而且有可能还是太大的,多数应用程序只使用3~10个描述符.而如今的网络服务器小小的都有几万的连接,虽然可以使用多线程多进程(也就有N*1024个).但是这样处理起来既