关于SOCKET数据通讯的问题(200分少再加)
高分求SOCKET数据通讯的源码,
要求一个服务端和N个客务端进行通讯,要求客务端发消息到服务端,服务端到回消息到客务端,
问几个小问题:
1. 当前服务端收到客务端的消息后,怎么能获得当前客务端的IP,
2. 怎样能锁定每一个客务端发送消息到服务端后,服务端会把客务端的消息写入XML文档里,如果N个客务端同时发消息到服务端,哪服务端同时把N个客务端的消息写入XML文档``时会出问题? 怎么解决呢?
有源码吗?
分少了再加```
问题点数:200、回复次数:33Top
1 楼mywebcom(我)回复于 2004-08-02 14:49:15 得分 10
1、当服务器端受到客户端的数据包,这数据包就包含了客户的地址,可以分离出来;
2、其实就算有很多客户同时发送消息到服务器端,也不用锁定服务器,只是让客户端的消息处于短暂的等待,形成队列,服务器端可以对不同的客户端建立一个xml文档,以后都是追加。
你亲自调试吧……Top
2 楼wybin(星雨)回复于 2004-08-02 15:24:42 得分 10
如果服务器端采用多线程的方式处理客户请求(以前C++的方式,C#中还没有关注过这部分),
可以考虑采用一个写XML文档的静态方法,然后在方法中对一个静态变量使用lock,
在lock块中操作XML文档,这样就可以保证文件写入安全了。
当然这样的话会引起线程等待。Top
3 楼Sunmast(速马@Redmond, WA)回复于 2004-08-02 15:38:18 得分 10
1. Socket.RemoteEndPoint
2. n个线程同时对一个XML文档写当然不行了,需要使用线程同步
http://www.microsoft.com/china/community/Column/94.mspxTop
4 楼xhunanpp(囨囚囨図)回复于 2004-08-02 15:58:13 得分 0
还有一个问题,当客务端联接服务端后, 如果关闭客务端, 服务端就会报错, 并且错误窗口都无法关闭```?Top
5 楼echero(迷失沙漠)回复于 2004-08-02 16:17:56 得分 24
服务器程序 mylisten.cs
用法:编译后直接运行。
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
public class mylisten
{
public static string data = null;
public static void StartListening()
{
byte[] bytes = new byte[1024];
IPHostEntry ipHostInfo = Dns.Resolve(Dns.GetHostName());
Console.WriteLine(ipHostInfo.HostName);
IPAddress ipAddress = ipHostInfo.AddressList[0];
IPEndPoint localEndPoint = new IPEndPoint(ipAddress,11000);
Socket listener = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
listener.Bind(localEndPoint);
listener.Listen(10);
bool cut = true;
while (cut)
{
Console.WriteLine("等待连接");
Socket handler = listener.Accept();
data = null;
bytes = new byte[1024];
int bytesRec = handler.Receive(bytes);
data += Encoding.Unicode.GetString(bytes,0,bytesRec);
Console.WriteLine("接受来自 " + handler.RemoteEndPoint.ToString() + " : " + data);
if (data == "close")
cut = false;
handler.Shutdown(SocketShutdown.Both);
handler.Close();
}
}
public static int Main(String[] args)
{
StartListening();
return 0;
}
}
客户机程序 mysend.cs
用法:编译后传递两个参数,第一个参数发送的信息,第二个参数,服务器程序的IP地址
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
public class mysend
{
public static void StartClient(string message,string address)
{
IPHostEntry ipHostInfo = Dns.Resolve(address);
IPAddress ipAddress = ipHostInfo.AddressList[0];
IPEndPoint remoteEP = new IPEndPoint(ipAddress,11000);
Socket sender = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
sender.Connect(remoteEP);
Console.WriteLine("连接到 " + sender.RemoteEndPoint.ToString());
byte[] msg = Encoding.Unicode.GetBytes(message);
sender.Send(msg);
sender.Shutdown(SocketShutdown.Both);
sender.Close();
}
public static void Main(String[] args)
{
StartClient(args[0],args[1]);
return;
}
}Top
6 楼zmgcj(真的名贵)回复于 2004-08-02 16:18:36 得分 2
客户端关闭之后会在服务端引发异常,在服务端的代码中加上捕获异常的代码,处理掉就可以了Top
7 楼amami(那那咪)回复于 2004-08-02 16:25:48 得分 0
UPTop
8 楼xhunanpp(囨囚囨図)回复于 2004-08-02 16:32:36 得分 0
to: zmgcj(真的名贵)
捕获异常是捕不了的,
跳出来的异常是系统的异常, 没法捕获到,Top
9 楼xhunanpp(囨囚囨図)回复于 2004-08-02 17:08:01 得分 0
to: echero(迷失沙漠)
你这个只能从客务端发送数据到服务端,但不能从服务端到客务端,
Top
10 楼chinawn(动性忍心)回复于 2004-08-02 17:25:11 得分 0
upTop
11 楼xhunanpp(囨囚囨図)回复于 2004-08-02 17:53:05 得分 0
异常错误是: "一个封锁操作被对 WSACancelBlockingCall的调用中断。"
然后再跳出: "未在侦听。请调用Start()方法",一直都关不掉这个错误窗口Top
12 楼echero(迷失沙漠)回复于 2004-08-03 13:35:18 得分 0
我没有写全
其余的道理是一样的
你看着写吗Top
13 楼1979xt(搞.NET三年多,现在有点迷惘.)回复于 2004-08-03 14:08:08 得分 5
http://www.aspcool.com/lanmu/browse1.asp?ID=892&bbsuser=csharpTop
14 楼tianxiake1()回复于 2004-08-03 14:46:31 得分 2
其实这个问题很好处理。
在服务端监听到客户端的时候,就开启一个线程来处理。而得到的socket实例就是针对这个客户端的。
最近我才做了个这样的程序,效果还可以Top
15 楼daguzhang(MoonWell)回复于 2004-08-03 14:58:24 得分 20
我刚做了一个网络麻将程序的框架:
private void Form1_Load(object sender, System.EventArgs e)
{
this.menuItem3.Enabled = false;
this.buttonSend.Enabled = false;
this.buttonAccept.Enabled = false;
}
private void button1_Click(object sender, System.EventArgs e)
{
//initialForm();
}
public void setListener()
{
int CurrentSocketNo = flag;
flag++;
try
{
Socket ClientSocket = (Socket)SocketList[CurrentSocketNo];
IPEndPoint epClient = (IPEndPoint)ClientSocket.RemoteEndPoint;
string ClientIP = epClient.Address.ToString();
string ClientPort = epClient.Port.ToString();
String ClientInfo = "Connected with "+ ClientIP + ": " + ClientPort;
this.listConnectedUsers.Items.Add(ClientInfo);
String welcomeMes = "Welcome to server!";
byte[] data = Encoding.Default.GetBytes(welcomeMes);
ClientSocket.Send(data,0,data.Length,SocketFlags.None);
//ClientSocket.Close();
while(true)
{
data = new byte[1024];
int count = ClientSocket.Receive(data);
string getString = Encoding.Default.GetString(data,0,count);
if(count!=0)
{
string revString = Encoding.Default.GetString(data,0,count);
foreach (Socket TempSocket in SocketList)
{
TempSocket.Send(data,0,data.Length,SocketFlags.None);
}
}
else
{
ClientInfo = "Disconnected with "+ ClientIP + ": " + ClientPort;
this.listConnectedUsers.Items.Add(ClientInfo);
ClientSocket.Shutdown(SocketShutdown.Both);
ClientSocket.Close();
SocketList.Remove(ClientSocket);
flag--;
break;
}
}
}
catch(SocketException ex)
{
MessageBox.Show(ex.ToString());
}
return;
}
public void Configuration()
{
try
{
Int32 port = 8088;
IPAddress localAddr =Dns.GetHostByName(Dns.GetHostName()).AddressList[0];//IPAddress.Parse("127.0.0.1");
ep = new IPEndPoint(localAddr,port);
serverSocket = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
serverSocket.Bind(ep);
serverSocket.Listen(4);
MessageBox.Show("配制服务器成功!");
serverExist = true;
this.menuItem2.Enabled = false;
this.menuItem3.Enabled = true;
}
catch(Exception ex)
{
MessageBox.Show(ex.ToString());
}
SocketList = new ArrayList(4);
flag = 0;
for(int i=0;i<4;i++)
{
Socket ClientSocket = serverSocket.Accept();
SocketList.Add(ClientSocket);
//MessageBox.Show(i.ToString()+" now the flag ="+flag.ToString());
ThreadStart myThreadDelegate = new ThreadStart(setListener);
Thread myThread = new Thread(myThreadDelegate);
myThread.Start();
}
}
private void menuItem2_Click(object sender, System.EventArgs e)
{
ThreadStart BeginListen = new ThreadStart(Configuration);
Thread myThread = new Thread(BeginListen);
myThread.Start();
}
public void beginReceive()
{
byte[] data;
while(true)
{
data = new byte[1024];
int count = clientSocket.Receive(data);
string revString = Encoding.Default.GetString(data,0,count);
this.listBoxChatContent.Items.Add(revString);
}
}
public void runClient()
{
string revString = String.Empty;
byte[] data = new byte[1024];
int count = clientSocket.Receive(data);
revString = Encoding.Default.GetString(data,0,count);
this.listBoxChatContent.Items.Add(revString);
ThreadStart BeginListen = new ThreadStart(beginReceive);
ClientRevThread = new Thread(BeginListen);
ClientRevThread.Start();
}
private void button2_Click(object sender, System.EventArgs e)
{
if(this.button2.Text.Trim()=="连接")
{
clientSocket = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
clientExist = true;
if(this.IpAddress.Text.Trim()!=""&&this.Port.Text.Trim()!="")
{
string ipAddress=IpAddress.Text.Trim();
try
{
IPAddress ip = Dns.Resolve(ipAddress).AddressList[0];
Int32 port=Convert.ToInt32(Port.Text.Trim());
IPEndPoint ep =new IPEndPoint(ip,port);
clientSocket.Connect(ep);
MessageBox.Show("连接服务器成功!");
this.button2.Text="断开";
this.buttonSend.Enabled = true;
this.buttonAccept.Enabled = true;
}
catch
{
MessageBox.Show("连接服务器失败,请确保存在此服务器或服务器已启动!");
}
ThreadStart BeginListen = new ThreadStart(runClient);
ClientMainThread = new Thread(BeginListen);
ClientMainThread.Start();
}
else
{
MessageBox.Show("请填入完整的服务器信息!");
}
}
else
{
//ClientRevThread.Abort();
try
{
clientSocket.Shutdown(SocketShutdown.Both);
clientSocket.Close();
clientExist = false;
this.button2.Text="连接";
this.buttonSend.Enabled = false;
this.buttonAccept.Enabled = false;
}
catch
{
MessageBox.Show("关闭连接失败,请确保已经连接上了服务器!");
}
}
}
public void getData()
{
}
private void button3_Click(object sender, System.EventArgs e)
{
String sendString = this.words.Text;
if(sendString!="")
{
byte[] data = Encoding.Default.GetBytes(sendString);
clientSocket.Send(data,0,data.Length,SocketFlags.None);
}
}
private void menuItem3_Click(object sender, System.EventArgs e)
{
try
{
//serverSocket.Shutdown(SocketShutdown.Both);
serverSocket.Close();
this.menuItem2.Enabled = true;
this.menuItem3.Enabled = false;
serverExist = false;
MessageBox.Show("关闭监听成功!");
}
catch
{
MessageBox.Show("关闭监听失败!");
}
}
private void Form1_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
if(serverExist)
{
if(serverSocket.Blocking)
serverSocket.Close();
}
if(clientExist)
{
if(clientSocket.Blocking)
{
clientSocket.Shutdown(SocketShutdown.Both);
clientSocket.Close();
}
}
}
}
}Top
16 楼miqier(米琪儿)回复于 2004-08-03 14:59:09 得分 0
P2P通信的实例看来符合你的要求,如果需要的话,留下Mail.Top
17 楼daguzhang(MoonWell)回复于 2004-08-03 15:02:17 得分 5
定义的部分的部分长了 贴不出来,有问题的话发短消息我
Top
18 楼redbb(....DB & DEV....抵制日货,人人有责...)回复于 2004-08-03 19:57:51 得分 0
markTop
19 楼qunw(平行线)回复于 2004-08-04 09:26:06 得分 0
To:miqier(米琪儿)
学习:
wngwz@msn.comTop
20 楼Rockford(探索)回复于 2004-08-04 09:51:14 得分 0
resocman@hotmail.com
多谢!!!Top
21 楼miqier(米琪儿)回复于 2004-08-04 11:13:58 得分 0
给楼上的两位发了。Top
22 楼bbsuser()回复于 2004-08-04 11:22:58 得分 7
http://www.microsoft.com/china/community/Column/94.mspxTop
23 楼xhunanpp(囨囚囨図)回复于 2004-08-06 15:51:03 得分 0
to : miqier(米琪儿)
mail: xhunanpp@163.com
来一份看看,
Top
24 楼csq0516(阿松)回复于 2004-08-06 23:36:20 得分 0
upTop
25 楼gbbword(分不清)回复于 2004-08-07 00:30:21 得分 0
to : miqier(米琪儿)
gbbword123@21cn.com
我也想要一份谢谢!Top
26 楼Chimeny(水村)回复于 2004-08-07 09:52:23 得分 0
先顶一下
miqier(米琪儿)的程序能否也给我一份Look Look?
Chimeny@163.comTop
27 楼zhpsam109(JACKY.昊昊)回复于 2004-08-07 10:38:07 得分 0
学习!Top
28 楼miqier(米琪儿)回复于 2004-08-11 09:36:02 得分 100
楼上留MAIL的都发了。Top
29 楼dsclub(任搏软)回复于 2004-08-11 09:39:40 得分 0
dsclub@hotmail.com
UP+接分!Top
30 楼jun_01(无名小卒)回复于 2004-08-11 09:41:40 得分 0
请教,一个帖子如何发200分啊?Top
31 楼herony420(坦荡荡)回复于 2004-08-11 09:50:01 得分 5
csh420@126.com
谢谢
我觉得你的异常是由于线程间锁定造成的,你应该仔细检查一下Top
32 楼csq0516(阿松)回复于 2004-08-12 00:29:12 得分 0
upTop
33 楼wjy550(大闸蟹)回复于 2004-09-20 09:11:30 得分 0
我也要一份,EMAIL:wjy@hfasoft.comTop




