C# TCP/IP中的客户端和服务器在局域网或外网怎么通信呀?谁有完整的例子呀.

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C# TCP/IP中的客户端和服务器在局域网或外网怎么通信呀?谁有完整的例子呀.相关的知识,希望对你有一定的参考价值。

我们学校要做一个项目,老师说用TCP/IP进行通信.用C#中的WinForm做,要求服务器端和客户端之间能够进行通信.请问怎么弄呀?
至少两者之进能进行交互,发送消息呀,我现在用TCPClient做只能在本机进行通信,只要把服务器端和客户端分开放到局域网上的不同机子上就不能访问了.上面说什么C#TcpClient 由于目标机器积极拒绝,无法连接.也不知道是什么原因.我找了网上很多网友贴出来的代码做出来也是一样的结果.书上的也是.求各位大叔大婶.帮帮忙啦.有没有什么好的,完整的代码或解决方案就不要猫着了,贴出来吧.有步骤的话最好.最好是自己本人试过的.网络上的代码我已经看了个底朝天了.就不要复制上来了.谢谢.

这是我以前在学校的时候做的一个c/s系统里面的类似qq聊天工具
你看看。。
这是客服端的代码:
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 demo2

public partial class frmTouchWe : Form

Thread a;
//发送IP跟端口
private UdpClient udp = new UdpClient("127.0.0.1",9000);
//接收端口
private UdpClient udpSend = new UdpClient(8000);
private IPEndPoint ip = new IPEndPoint(IPAddress.Any,0);
public frmTouchWe()

InitializeComponent();
Form.CheckForIllegalCrossThreadCalls = false;


private void frmTouchWe_Load(object sender, EventArgs e)
//定义线程开始
a = new Thread(new ThreadStart(Run));
a.Start();

private void linkLabel1_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)

//客服接收信息。弹出窗体
frmAnswerInfo answerInfo = new frmAnswerInfo();
answerInfo.Show();

private void button1_Click(object sender, EventArgs e)

//在自己的信息栏中显示自己的信息
lsbInfo.Items.Add(txtInfo.Text);
//用户信息内容
string Mes = txtInfo.Text;
//用户信息
string mes = "用户:"+Program.user.id+"("+Program.user.name+")"+" " + time;
//转换成字节
byte[] b = UTF8Encoding.UTF8.GetBytes(Mes);
byte[] bb = UTF32Encoding.UTF8.GetBytes(mes);
//发送信息
udp.Send(bb, bb.Length);
udp.Send(b, b.Length);
txtInfo.Text = "";

//循环接受客服发来的信息
private void Run()

while (true)

byte[] b = udpSend.Receive(ref ip);
string mes = UTF8Encoding.UTF8.GetString(b);
lsbInfo.Items.Add(mes);



private void button2_Click(object sender, EventArgs e)

this.Close();


private void button3_Click_1(object sender, EventArgs e)

//清空所有项
lsbInfo.Items.Clear();




下面是服务器端的代码
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 demo2

public partial class frmAnswerInfo : Form

//定义一条线程,用来循环接收客户发来的信息
Thread a;
//定义另一条线程,用来升起窗体
Thread b;
//发送到信息的地址
private UdpClient udpSend = new UdpClient("127.0.0.1",8000);
//接收端口
private UdpClient udp = new UdpClient(9000);
private IPEndPoint ip = new IPEndPoint(IPAddress.Any,0);
public frmAnswerInfo()

InitializeComponent();
Form.CheckForIllegalCrossThreadCalls = false;

//循环接收信息
private void Run()

while (true)

byte[] b = udp.Receive(ref ip);
string mes = UTF8Encoding.UTF8.GetString(b);
lsbInfo.Items.Add(mes);



private void frmAnswerInfo_Load(object sender, EventArgs e)

//设置窗体的位置属性(窗体加载时候慢慢从右下角升上来~类似qq广告~~)
this.Top = Screen.PrimaryScreen.WorkingArea.Height;
this.Left = Screen.PrimaryScreen.WorkingArea.Width - this.Width;
//设置窗体的名字
a = new Thread(new ThreadStart(Run));

b = new Thread(new ThreadStart(run));
//开始线程
a.Start();
b.Start();

//用户点击谈话时显示该窗体
private void run()

while (true)

this.Top = this.Top - 10;
Thread.Sleep(100);
if (Screen.PrimaryScreen.WorkingArea.Height - this.Height >= this.Top)

break;



//发送按钮编码
private void button1_Click(object sender, EventArgs e)

//获取当前时间
DateTime time = DateTime.Now;
//在自己的信息栏中显示自己发出去的信息
lsbInfo.Items.Add("在线客服:"+time);
lsbInfo.Items.Add(txtInfo.Text);

//在客户端显示自己的信息标题
string mes = "在线客服:"+time;
//信息内容
string Mes = txtInfo.Text;
//发送信息标题
byte[] b = UTF8Encoding.UTF8.GetBytes(mes);
//发送信息内容
byte[] bb = UTF8Encoding.UTF8.GetBytes(Mes);
udpSend.Send(b, b.Length);
udpSend.Send(bb,bb.Length);
txtInfo.Text = "";


private void button2_Click(object sender, EventArgs e)

this.Close();


private void button3_Click(object sender, EventArgs e)

//清除所有项
lsbInfo.Items.Clear();




这个可以跑的。。我以前就用过的。
参考技术A socket,局域网 是没有问题的,但是广域网,需要用p2p

我这里有老外写得socket、server和client,非p2p,在局域网测试过了。
但是代码太长,贴不完,需要的话 留下mail。
参考技术B 这个得用p2p技术,普通的tcp/ip无法直接突破不同网段.
参看网址http://developer.51cto.com/art/200602/21200.htm
参考技术C 把机器防火墙关了,地址对,端口可用肯定连得上 参考技术D 项目?不会是北大青鸟的QQ吧。。。

在 C# 5 中使用 async/await 模式编写高度可扩展的 TCP/IP 服务器?

【中文标题】在 C# 5 中使用 async/await 模式编写高度可扩展的 TCP/IP 服务器?【英文标题】:Writing a highly scalable TCP/IP server in C# 5 with the async/await pattern? 【发布时间】:2013-01-15 17:45:36 【问题描述】:

我的任务是设计一个相当简单的 TCP/IP 服务器,它必须接受来自多个客户端的连接。它需要用 C# 编写,我使用的是 .NET 4.5。也就是说,我不确定 .NET 4.5 中 TCP/IP 服务器/客户端可扩展性的当前“最新技术”是什么。

我确实看到了这个帖子:How to write a scalable Tcp/Ip based server。但这与 .NET 2.0 和 3.5 相关,并且没有提及 async/await 模式。

我能够以“旧方式”编写服务器......但我想知道“新方式”是什么。

使用 Socket、TcpClient 或 TcpListener 上的新 Async 方法在 C# 中创建可扩展服务器的最佳方式是什么? 新的异步方法是否利用 I/O 完成端口? 滚动您自己的 Socket 侦听器效率更高,还是 TcpListener/TcpClient 类现在非常好?

编辑:其他问题。

【问题讨论】:

没有 C# 4.5 :) 它是 .net 4.5,C# 5 这可能有用 - blogs.msdn.com/b/pfxteam/archive/2011/12/15/10248293.aspx @SoroushFalahati:使用 I/O 完成端口的异步不应阻塞线程。事实上,.NET 3.5 和更高版本中的大多数 Begin/AsyncResult 类型的 I/O 方法都利用 IOCP,因此它们不应该像 .NET 2.0 中的异步那样阻塞任何线程。 @SoroushFalahati:实际上,我很确定绝大多数浏览器和 Web 服务器都使用 asynchronous 方法。特别是基于 IOCP。 您是否考虑过使用networkcomms.net等网络库?这里有一个很好的例子networkcomms.net/creating-a-wpf-chat-client-server-application 【参考方案1】:

在 Socket、TcpClient 或 TcpListener 上使用新的 Async 方法在 C# 中创建可扩展服务器的最佳方式是什么?

Socket 上没有任何新的 async 方法; Socket 上名为 *Async 的方法是一组特殊的 API,用于减少内存使用。 TcpClientTcpListener 确实得到了一些新的 async 方法。

如果您想要最好的可扩展性,最好使用Stephen Toub's custom awaiters for Socket。如果您想要最简单的代码,最好使用TcpClientTcpListener

新的异步方法是否利用 I/O 完成端口?

是的,就像 BCL 中的大多数其他异步 API 一样。 AFAIK,Stream 类是唯一可能不使用 IOCP 的类;所有其他 *Begin/*End/*Async 方法都使用 IOCP。

滚动您自己的 Socket 侦听器效率更高,还是 TcpListener/TcpClient 类现在非常好?

这些课程非常好。 Stephen Toub 有一个blog post,它在内存使用方面效率更高。

【讨论】:

与问题无关,什么是IO Completion port?对不起,VB背景让我没有遇到这个。谢谢。 @StaurtDunkeld 链接了上面的那篇文章。我看了看它,我想我没有注意到它试图创建一个更有效的侦听器/客户端。我试图了解是什么使它更高效的内存。是不是你不需要实例化一个 TcpClient 并保留它来管理连接? @shahkalpesh:An efficient way to handle lots of asynchronous I/O。 .NET 目前每个应用程序域使用一个 IOCP,绑定到线程池。 @blesh:不;这是因为它使用了 Socket *Async 方法。通常,异步操作需要为每个操作分配一个结构(IAsyncResult,类似于OVERLAPPED)。 Socket *Async 方法使用SocketAsyncEventArgs,有点像可重复使用的IAsyncResult。因此分配/解除分配更少,对 GC 的压力也更小。 感谢您的回答。我想我要做的是使用 TcpListener/TcpClient 并将它们抽象出来,所以如果我以后需要使用 Toub 的方法进行优化,我可以。

以上是关于C# TCP/IP中的客户端和服务器在局域网或外网怎么通信呀?谁有完整的例子呀.的主要内容,如果未能解决你的问题,请参考以下文章

C#的web项目怎么实现tcp/ip通信呢

c# TCP/IP 自动断开

u3d局域网游戏网络(c# socket select 模型)

如何在 C# 中处理多个客户端 TCP/IP

请问计算机使用的无线网络使用的是TCP/IP协议吗?

C# 使用 tcp/ip 从 Minecraft 服务器获取数据包