-
17-10-2010, 05:11 PM #1Junior Member
- Ngày tham gia
- Sep 2015
- Bài viết
- 0
lỗi khó hiểu khi send dữ liệu qua mạng lan
mình tạo ra 1 struct Message
Mã nguồn PHP:struct Message { int messtype; char data[2048]; };
mình dùng TCP để trao đổi dữ liệu
client send 1 lần 1 message khi server nhận được message rồi thì báo lại cho client và client tự động send message tiếp theo(tiến hành 10 lần như vậy).
có 1 vấn đề mình gặp phải là.
trường hợp 1
test trên cùng 1 máy(server sẽ lắng nghe trên cổng loopback của máy(127.0.0.1)) thì 10 message đều nhận đủ
trường hợp 2
test trên 2 máy khác nhau thì server nhận được 10 gói nhưng phần data[] không có dữ liệu
trường hợp 3
tiến hành debug quá trình gủi và nhận của trường hợp 2
kết quả là nhận đủ 10 gói bao gồm cả phần data[]
vậy lỗi trên do đâu mà ra.ai biết chỉ giúp mìnhView more random threads:
- cho hỏi về cách xuat du liệu ra edit box
- Lỗi khi chạy chương trình rồi vụt tắt 0xc0000013
- chương trình bằng MFC mà có máy chạy máy không?
- Xin tài liệu lập trinh kết nối với Camera và truyền tín hiệu từ Camera trên mạng
- Convert BMP to RBG | Chuyển ảnh từ Bitmap sang Vector. Giúp mình sửa lỗi???
- Cách truyền 1 chuỗi từ VB vào dll như thế nào ?
- Cấp phát động lập trình hướng đối tượng
- Lỗi linker khi tạo mới project MFC
- Trục trặc trong việc tạo một dialog đơn giản
- Làm thế nào để lập trình với VC++ 6?
-
17-10-2010, 06:27 PM #2Junior Member
- Ngày tham gia
- Sep 2015
- Bài viết
- 0
Cho xem code cái đoạn nhận dữ liệu coi nào.
Cái đoạn gọi hàm recv() ấy [IMG]images/smilies/smile.png[/IMG]
-
18-10-2010, 10:41 AM #3Junior Member
- Ngày tham gia
- Sep 2015
- Bài viết
- 0
thank bạn.mình set data lại 1000 byte thì ok.mình nắm chưa chắc được quá trình send & recv hàm recv mình xin hỏi thêm vài câu nữa
bạn có biết hàm recv() nhận tối đa trong 1 lần là bao nhiêu byte không?hay là nó nhận bất kì 1 giá trị nào đó (0-->vô cùng)?
Giả sử mỗi lần bạn gửi đi là 2052 bytes mà ở ngay cái thời điểm bạn nhận về được có 100 bytes bạn cũng đem ra xử lý ngay à? --> Sai[/U][/U]
vấn đề mình đang và rất thắc mắc ở chỗ này đây,nếu mình send khoảng 1000 byte mà nó nhận 50 byte thì mình thật sự chưa biết giải quyết thế nào.vì 1 ứng dụng có rất nhiều client và hàm recv() sẽ làm việc khi có sự kiện FD_READ nên rất khó để biết đâu là thông điêp của client nào
mình ví dụ.
2 client:client1 và client2.cùng send 1 lúc mỗi client 1 Message
phía Server
khi có sụ kiện FD_READ
Server recv() nhận được 4 byte(giả sử lúc này là message của client1)
-->chưa đủ 1 Message
vậy Server recv() tiếp được 1000byte. hai lần nhận được 1004 byte
-->đủ 1 Message
nhưng 1000 byte nhận sau là của client2 thì sao?làm sao quản lý chỗ này
-
18-10-2010, 11:26 AM #4Junior Member
- Ngày tham gia
- Sep 2015
- Bài viết
- 0
Gửi bởi rua_con
vấn đề mình đang và rất thắc mắc ở chỗ này đây,nếu mình send khoảng 1000 byte mà nó nhận 50 byte thì mình thật sự chưa biết giải quyết thế nào.vì 1 ứng dụng có rất nhiều client và hàm recv() sẽ làm việc khi có sự kiện FD_READ nên rất khó để biết đâu là thông điêp của client nào
mình ví dụ.
2 client:client1 và client2.cùng send 1 lúc mỗi client 1 Message
phía Server
khi có sụ kiện FD_READ
Server recv() nhận được 4 byte(giả sử lúc này là message của client1)
-->chưa đủ 1 Message
vậy Server recv() tiếp được 1000byte. hai lần nhận được 1004 byte
-->đủ 1 Message
nhưng 1000 byte nhận sau là của client2 thì sao?làm sao quản lý chỗ này
Muốn biết đủ hay chưa đủ bản tin thì đơn giản thôi.
Mỗi buffer lại có 1 thông số là hiện đang lưu trữ bao nhiêu dữ liệu nhận được (remaining - khởi đầu chưa nhận thì cho remaining = 0)
Tớ phác thảo thế này:
Mã:unsigned char buffer[4096] //buffer để nhận dữ liệu (của riêng mỗi socket)unsigned int remaining = 0; //số bytes còn lại chưa xử lý trong buffervoid OnReceive(int nErrorCode){ int received = recv(sock, /hận trên socket nào buffer + remaining, /hận dữ liệu bắt đầu từ vị trí remaining của buffer sizeof(buffer) - remaining, //số lượng bytes tối đa có thể nhận được vào buffer 0); // if(received > 0) remaining += received; //cập nhật số byte chưa được xử lý trong buffer unsigned char* buf = buffer;//lấy 1 biến tạm để xử lý dữ liệu while(remaining >= sizeof(Message)) //khi nào số lượng byte dữ liệu chưa xử lý có kích cỡ lớn hơn 1 message { Message* msg = (Message *)buf; //làm gì đó với cái message này // .... //Xử lý xong message rồi buf += sizeof(Message);//chuyển đến đầu của message kế tiếp remaining -= sizeof(Message); // cập nhật lại số lượng byte chưa xử lý } //dữ liệu còn dư lại không đủ 1 message //cập nhật lại vùng lưu trữ dữ liệu //Đưa vùng dữ liệu chưa xử lý về đầu buffer memcpy(buffer, buf, remaining);}
-
18-10-2010, 05:15 PM #5Junior Member
- Ngày tham gia
- Sep 2015
- Bài viết
- 0
Gửi bởi namdq2kMã:Phần nhận nó sẽ tương tự như vầy.bạn xem thử
Mã nguồn PHP:recv(Server, (char*)&mess,GetSize(mess),0); /*sử lý dữ liệu nhận được*/ .............. /*báo lại cho client biết đã nhận được Message để client send tiếp*/ ..............
Mã nguồn PHP:/*hàm GetSize()*/ int GetSize(const Message &mess) { return(sizeof(mess.messtype) + sizeof(mess.data)); }
-
18-10-2010, 05:29 PM #6Silver member
- Ngày tham gia
- Sep 2015
- Đang ở
- Hà Nội
- Bài viết
- 0
<div class="bbcode_quote">
<div class="quote_container">
<div class="bbcode_postedby">
[IMG]images/misc/quote_icon.png[/IMG] Nguyên bản được gửi bởi <strong>rua_con</strong>
[IMG]images/buttons/viewpost-right.png[/IMG]
<div class="message">Mã:Phần nhận nó sẽ tương tự như vầy.bạn xem thử
Mã:int received = recv(SOCKET s, char* buff, int len, int flag);
Hàm này trả về số byte nhận được. Giả sử mỗi lần bạn gửi đi là 2052 bytes mà ở ngay cái thời điểm bạn nhận về được có 100 bytes bạn cũng đem ra xử lý ngay à? --> Sai.
Bạn phải có 1 cơ chế để biết rằng đã nhận đầy đủ 1 bản tin [IMG]images/smilies/smile.png[/IMG]
3. Hàm getsize của bạn sao dài dòng thế?
Mã:return sizeof(mess);
-
23-10-2010, 01:21 PM #7Junior Member
- Ngày tham gia
- Sep 2015
- Bài viết
- 0
tuần vừa rồi bận quá nên không làm tiếp được
nói chung thì mình send và nhận ok rồi nhưng mà theo như lý thuyết thì bài mình làm vẫn có thể bị lỗi[IMG]images/smilies/smile.png[/IMG]
Mã:vì chỗ này vẫn có thể sảy ra lỗi
Mã nguồn PHP:int received = recv(sock, /hận trên socket nào buffer + remaining, /hận dữ liệu bắt đầu từ vị trí remaining của buffer sizeof(buffer) - remaining, //số lượng bytes tối đa có thể nhận được vào buffer 0); //
<div class="bbcode_description">HTML Code:
50%Message1 ->50%Message2 ->50%Message1 ->50% Message2
</div>vậy đoạn code trên sẽ nhận
<div class="bbcode_description">HTML Code:
Message1 = 50%Message1 + 50%Message2
Message2 = 50%Message1 + 50%Message2
</div>==>tiêu vậy trường hợp này không thể dựa vào socket nào để sét xem dữ liệu của client nào được rồi vì trường hợp này cùng 1 một client mà.không biết mình có lầm chỗ nào không bạn xem và góp ý dùm mình
-
23-10-2010, 02:00 PM #8Junior Member
- Ngày tham gia
- Sep 2015
- Bài viết
- 0
Gửi bởi rua_con
Message2 = 50%Message1 + 50%Message2
</div>==>tiêu vậy trường hợp này không thể dựa vào socket nào để sét xem dữ liệu của client nào được rồi vì trường hợp này cùng 1 một client mà.không biết mình có lầm chỗ nào không bạn xem và góp ý dùm mình</div>
</div>
</div>
</div>Bạn đọc lại lý thuyết về TCP trước khi code đi. Làm gì có cái chuyện mạng ở dưới nó gửi lung tung như thế. Nó đảm bảo tính thứ tự của từng byte gửi đi.
-
23-10-2010, 02:29 PM #9Junior Member
- Ngày tham gia
- Sep 2015
- Bài viết
- 0
mình đã đọc về tcp có lẽ mình hiểu sai đây là suy nghĩ của mình về tcp sai chỗ nào thì bạn nhắc dùm mình mình k sợ bị chửi ngu đâu
mỗi Message của mình là 2000byte TCP dựa vào MTU để quyết định cắt Message của mình ra làm bao nhiêu gói giả sử trong trường hợp này nó cắt message làm 2 gói(mỗi gói 1000byte
vậy khi client send 1 message thì chia làm 2 gói tin và send đi khi server nhận được gói tin thứ nhất nghĩa là 1000byte đầu tiên của Message1 thì phát sinh sự kiện FD_READ lúc đó server sẽ recv gói tin này?
trong lúc client send message1 thì nó đồng thời send thêm 1 message2 giả sử gói tin thứ 2 của message1 gặp phải sự có nào đó chưa đến server được và server yêu cầu send lại.cũng trong lúc này gói tin thứ nhất của message2 đến và server phát sinh sự kiền FD_READ recv gói tin này ==>Mã:Message1 = 50%Message1 + 50%Message2
Mã nguồn PHP:mình hiểu sai chỗ nào thì bạn nhắc dùm mình
-
23-10-2010, 03:25 PM #10Junior Member
- Ngày tham gia
- Sep 2015
- Bài viết
- 0
http://vi.wikipedia.org/wiki/TCP/IP
TCP là một giao thức định hướng kết nối. Nó giải quyết nhiều vấn đề độ tin cậy để cung cấp một dòng byte đáng tin cậy (reliable byte stream):
- Dữ liệu đến đích đúng thứ tự Sửa lỗi dữ liệu ở mức độ tối thiểu Dữ liệu trùng lặp bị loại bỏ Các gói tin bị thất lại/loại bỏ được gửi lại Có kiểm soát tắc nghẽn giao thông dữ liệu
Thông qua phân tích dữ liệu Google từ 86 quốc gia, mới đây, một công ty tại Anh đã công bố bảng xếp hạng kích tấc "cậu nhỏ" của các nước trên thế giới. Kết quả, hầu hết các nước xếp ở nhóm đầu của...
"Chim" của chàng trai Việt thuộc...