Read-only archive. Login and posting are unavailable.

PDA

View Full Version : Bác nào rành về lập trình mạng trong C# giúp mình cái này với


money10289
17-02-2011, 13:27
Mình có làm 1 kết nối client server sử dụng threads, chạy thì nó báo lỗi này :surrender:
Only one usage of each socket address (protocol/network address/port) is normally permitted.
Đây là code:
public partial class Sever : Form
{
TcpListener client;
byte[] data = new byte[1024];
IPAddress ip;

public Sever()
{
InitializeComponent();
textBox_Port.Text = "8888";
string hostName = Dns.GetHostName();
IPHostEntry ipHostInfo = Dns.GetHostEntry(hostName);
ip = ipHostInfo.AddressList[0];

string ipAddress = Dns.GetHostByName(hostName).AddressList[0].ToString();
textBox_IP.Text = ipAddress;


try
{
IPEndPoint ipe = new IPEndPoint(ip, Convert.ToInt32(textBox_Port.Text));
client = new TcpListener(ipe);
}
catch
{
MessageBox.Show("Kiem tra lai dia chi ip va port");
return;
}

client.Start(); // Lỗi ngay dòng này
textBox_Status.Text = "Waiting for Clients.....";
button_start.Text = "Stop";
while (true) //khi bỏ dòng lap while này thì k bao lỗi nữa
{
if (client.Pending())
{

ConnectionThread newconnection = new ConnectionThread(listBox1, textBox_Status);
newconnection.threadListener = this.client;
ThreadPool.QueueUserWorkItem(new WaitCallback(newconnection.HandleConnection));
}
else
Thread.Sleep(1000);
}
}
}

Mình có hỏi 1 số diễn đàn cntt gòi nhưng chờ lâu quá chưa có ai giúp nên mạng phép mượn f17 nhờ cái vozer, e đang cần gấp lắm ah!:pudency:

Bumc6
17-02-2011, 13:38
Muốn giúp qá :rofl: nhưng em mới học 2 cái WriteLine và ReadLine thôi ợ :rofl:

LokiDClone
17-02-2011, 13:40
Muốn giúp qá :rofl: nhưng em mới học 2 cái WriteLine và ReadLine thôi ợ :rofl:

tốt bụng quá :gach::gach::gach::gach::gach:

BennyDoan
17-02-2011, 13:50
Nếu bạn dùng While thì cái điều kiện :
client.Start(); // Lỗi ngay dòng này
textBox_Status.Text = "Waiting for Clients.....";
button_start.Text = "Stop";
đảm bảo phải đúng thì While nó mới chạy. Mình nghĩ điều kiện của bạn đã sai nên mới báo lỗi ở client.start()

Bạn thử dùng do while xem sao hoặc kiểm tra lại điều kiện của nó.

Jay
17-02-2011, 13:52
đoán mò nhé:
Nếu thực sự lỗi ở dòng start thì dự đoán do vô tình tạo 2 listener trên cùng 1 port, tức là class Server được khởi tạo 2 lần ở đâu đấy (do port set tĩnh là 8888), hoặc là port 8888 đó đang được sử dụng bởi thằng nào khác trên máy mà mình ko biết.

Tuy nhiên theo như nói bỏ vòng lặp while đi thì ko bị lỗi nữa, suy ra chỉ còn 1 lý do là Server được tạo 2 lần mà thôi.

money10289
17-02-2011, 13:59
Nếu bạn dùng While thì cái điều kiện :

đảm bảo phải đúng thì While nó mới chạy. Mình nghĩ điều kiện của bạn đã sai nên mới báo lỗi ở client.start()

Bạn thử dùng do while xem sao hoặc kiểm tra lại điều kiện của nó.

Code này mình lấy từ vd trong sách, mà khi bỏ vòng lập while k bỏ các lệnh trong đó thì nó vẫn chạy nhưng k đúng yêu cầu vì cần lập lại dòng lệnh đó để nhận client kết nối

BennyDoan
17-02-2011, 14:12
Code này mình lấy từ vd trong sách, mà khi bỏ vòng lập while k bỏ các lệnh trong đó thì nó vẫn chạy nhưng k đúng yêu cầu vì cần lập lại dòng lệnh đó để nhận client kết nối

Khi bạn bỏ While đi thì nghĩa là các câu lệnh bên trong While đó chẳng cần phải kiểm tra điều kiện gì nữa thì lệnh vẫn sẽ chạy lần lượt theo từng dòng lệnh thôi.

Khả năng khi cho while vào nên cái client.pending() ko biêt phản hổi từ đâu.

akachai
17-02-2011, 14:15
ngày trước em hay dùng port 8080. bác thử sửa lại port trong file log xem :)

Phong.dq_never_lifted
17-02-2011, 14:17
post thông báo lỗi lên đây đi cậu...

BennyDoan
17-02-2011, 14:18
ngày trước em hay dùng port 8080. bác thử sửa lại port trong file log xem :)

Cũng có thể là bị khóa các port nhưng dùng máy cá nhân thì đâu có bị giới hạn khóa port đâu.

Jay
17-02-2011, 14:20
bên trong cái hàm HandleConnection là làm gì post lên luôn đi.

kissmevn
17-02-2011, 14:25
Thay đỏi port đi, port 8888 hay được dùng lắm.
Không thì dùng hàm random từ 10k đổ lên để chọn port(dải này ít bị sử dụng)

Phong.dq_never_lifted
17-02-2011, 14:27
ko phải lỗi ở port.

money10289
17-02-2011, 14:30
Đây là code của lớp ConnectionThread ah
class ConnectionThread
{
public TcpListener threadListener;
private static int connections = 0;
public void HandleConnection(object state)
{
int recv;
byte[] data = new byte[1024];
TcpClient client = threadListener.AcceptTcpClient();
NetworkStream ns = client.GetStream();
connections++;
Console.WriteLine("New client accepted: {0} active connections",
connections);
string welcome = "Welcome to my test server";
data = Encoding.ASCII.GetBytes(welcome);
ns.Write(data, 0, data.Length);
while(true)
{
data = new byte[1024];
recv = ns.Read(data, 0, data.Length);
if (recv == 0)
break;

ns.Write(data, 0, recv);
}
ns.Close();
client.Close();
connections—;
Console.WriteLine("Client disconnected: {0} active connections",
connections);
}
}

Hàm HandleConnection đc gọi khi có 1 client kết nối tới

Đây là em lấy nguyên mẫu trong sách chạy vẫn lỗi:pudency:

money10289
17-02-2011, 14:33
Thay đỏi port đi, port 8888 hay được dùng lắm.
Không thì dùng hàm random từ 10k đổ lên để chọn port(dải này ít bị sử dụng)

e đổi đủ thứ port hết gòi bác :((

Phong.dq_never_lifted
17-02-2011, 14:35
alo. cậu đưa project lên đây đi, ngồi nhìn code đoán mò thế này thì đỡ sao được. :gach:

kissmevn
17-02-2011, 14:43
Google thần chưởng ra được cái này, chủ thớt apply thử xem

http://chantroitinhoc.niceboard.net/t88-chuong-trinh-chat-viet-bang-c

Jay
17-02-2011, 14:45
bỏ cái Threadpool lúc gọi HandleConnection đi. gọi trực tiếp cho nó xử lý đồng bộ luôn. Mô tả sơ sơ như sau:

khi client.pending() == true lần đầu tiên trong vòng while, nó tạo 1 thread để gọi handleconnection sau dó lập tức loop 1 lần nữa. Lúc đó thì cái handleconnection vẫn đang chạy, tức là cái TcpClient vẫn còn sống, và pending() vẫn trả về true, và theo kịch bản cũ thì lại tạo 1 thread mới để gọi handleconnection 1 lần nữa, và lại AcceptTcpClient() 1 lần nữa --> báo lỗi.

Giờ nếu bỏ cái Threadpool chổ gọi handleconnection đi, ép nó phải xử lý xong cái message đó, đóng cái TcpClient, rồi mới lặp tiếp vòng while thì sẽ không bị lỗi nữa.

money10289
17-02-2011, 15:00
Google thần chưởng ra được cái này, chủ thớt apply thử xem

http://chantroitinhoc.niceboard.net/t88-chuong-trinh-chat-viet-bang-c

Cái chương trình này là lấy chình xác từ cái tài liệu e đang đọc, nhưng cũng cảm ơn bác nhìu :byebye:


bỏ cái Threadpool lúc gọi HandleConnection đi. gọi trực tiếp cho nó xử lý đồng bộ luôn. Mô tả sơ sơ như sau:

khi client.pending() == true lần đầu tiên trong vòng while, nó tạo 1 thread để gọi handleconnection sau dó lập tức loop 1 lần nữa. Lúc đó thì cái handleconnection vẫn đang chạy, tức là cái TcpClient vẫn còn sống, và pending() vẫn trả về true, và theo kịch bản cũ thì lại tạo 1 thread mới để gọi handleconnection 1 lần nữa, và lại AcceptTcpClient() 1 lần nữa --> báo lỗi.

Giờ nếu bỏ cái Threadpool chổ gọi handleconnection đi, ép nó phải xử lý xong cái message đó, đóng cái TcpClient, rồi mới lặp tiếp vòng while thì sẽ không bị lỗi nữa.

Cảm ớn a, để e thử

money10289
17-02-2011, 21:24
bỏ cái Threadpool lúc gọi HandleConnection đi. gọi trực tiếp cho nó xử lý đồng bộ luôn. Mô tả sơ sơ như sau:

khi client.pending() == true lần đầu tiên trong vòng while, nó tạo 1 thread để gọi handleconnection sau dó lập tức loop 1 lần nữa. Lúc đó thì cái handleconnection vẫn đang chạy, tức là cái TcpClient vẫn còn sống, và pending() vẫn trả về true, và theo kịch bản cũ thì lại tạo 1 thread mới để gọi handleconnection 1 lần nữa, và lại AcceptTcpClient() 1 lần nữa --> báo lỗi.

Giờ nếu bỏ cái Threadpool chổ gọi handleconnection đi, ép nó phải xử lý xong cái message đó, đóng cái TcpClient, rồi mới lặp tiếp vòng while thì sẽ không bị lỗi nữa.

Em debug thì nó chạy đến start() đã báo lỗi gòi thì là sao nó tạo thread đc, vẫn chưa hiểu tại k bỏ while thì lại k lỗi nữa, mọi tài liệu trên mạng đều xài zậy mà ?:sosad:

Rosario
17-02-2011, 21:43
Vì bạn ko post cả project lên nên ko sure lắm, nhưng nhìn cách code củ chuối quá, đừng có bao giờ khởi tạo biến gì trong try-catch (trường hợp của bạn là câu client = new TcpListener(ipe); ) . Nếu có thì chỉ dùng biến đó trong try-catch thôi, ko dễ lỗi lắm. Vì vậy đầu tiên bạn hãy đưa cái câu khởi tạo kia ra ngoài đã rồi nói chuyện tiếp.

money10289
17-02-2011, 22:23
Cái đó là hình test thử phải lỗi chỗ đó không post lên đây nên chưa kịp xóa, còn toàn bộ phần code đó thì nó gần như giống trong sách hết bạn ah`

Rosario
17-02-2011, 22:28
Thế tóm lại là bỏ cái đoạn try-catch đấy đi chưa đã ? (để chắc chắn rằng lỗi ko phát sinh do việc khởi tạo biến trong try-catch) . Mình ko lập trình mạng, nhưng với con mắt nhìn của mình thì thấy chỗ đó là nguy hiểm. Sau khi bỏ try-catch thì lỗi vẫn như cũ à ?

money10289
17-02-2011, 22:33
Code lúc đầu k có đoạn try catch, mình mới thêm vào xem để xem có lỗi j khi tạo ipAddress k thôi, k hĩu là mình đã chịnh lai code jong hoàn toàn trong sách nhưng vẫn bị lỗi này

Rosario
17-02-2011, 22:46
Up cả cái project lên đây xem nào. Ngồi đoán già đoán non khổ lắm

kabunovn
17-02-2011, 22:56
Sách gì đó bạn, e-book à .Up lên cho mình với.Đang cần tìm tài liệu học phần này:beauty:

money10289
17-02-2011, 23:43
Đây nè bạn: C.Sharp.Network.Programming.(2003) + các giải pháp lập trình C# gg là ra.

Project mình đang sửa lại 1 số chổ, đêm nay xong chắc mình cũng post lên nhờ các vozer quá :D!