积极答复者
TCP 程序的一些问题

问题
-
各位,请问一下,我在建立tcp连接的时候,使用源代码进行字符串连接的时候,已经成功了,但是转成图片的时候,除了一堆问题,现在两者之间的连接都连接了,不知道出了什么问题,请问有谁能给我一些指导吗?谢谢
Server 代码:
#pragma comment(lib, "ws2_32.lib")
#include <cstdio>
#include <iostream>
#include <WinSock2.h>
#include <Windows.h>
#include<opencv2/opencv.hpp>
using namespace std;
using namespace cv;
char * recvbuf;
int main()
{
// Hilfsvariable
long res;
// Versionsdaten
WSADATA wsaData;
// ws2_32.dll aktivieren
res = WSAStartup(MAKEWORD(2, 1), &wsaData);
if(res == 0 )
cout << "WSAStartup()\t\t successful" << endl;
else
cout << "error WSAStartup(): " << WSAGetLastError() << endl;
// Socket Deskriptoren
SOCKET slisten, client;
// Socket anforder bzw. Kommunikationsendpunkt einrichten
slisten = socket(AF_INET, SOCK_STREAM, 0);
if(slisten != INVALID_SOCKET )
cout << "socket() \t\t successful" << endl;
else
cout << "error socket(): " << WSAGetLastError() << endl;
// Verbindungsinformationen
sockaddr_in info;
// sockaddr
info.sin_addr.s_addr = inet_addr("158.132.8.117");
info.sin_family
= AF_INET;
info.sin_port
= htons(9992);
int infolen = sizeof(info);
res = bind(slisten, (struct sockaddr*)&info, infolen);
if(res != SOCKET_ERROR )
cout << "bind() \t\t successful" << endl;
else
cout << "error bind(): " << WSAGetLastError() << endl;
// Warteschlange f黵 einkommende Verbindungen
res = listen(slisten, SOMAXCONN);
if(res != SOCKET_ERROR )
cout << "listen() \t\t successful" << endl;
else
cout << "error listen(): " << WSAGetLastError() << endl;
sockaddr_in clientinfo;
int clientinfolen = sizeof(clientinfo);
client = accept(slisten, (struct sockaddr*)&clientinfo, &clientinfolen);
if(client != SOCKET_ERROR)
cout << "client accepted: " << inet_ntoa(clientinfo.sin_addr) << ":"
<< ntohs(clientinfo.sin_port) << endl;
while(1)
{
// Verbindung aus der Warteschlange abholen
// 黚er das Socket kommunizieren
/*res = send(client, "server message received", strlen("server message received"), 0);
if(res == SOCKET_ERROR)
cout << "error send()" << WSAGetLastError() << endl;*/
res = recv(client, recvbuf, 1000, 0);
uchar* data2;
data2 = (uchar *)recvbuf;
Mat image = Mat(500, 500, CV_8UC3);
image.data = data2;
if(res == SOCKET_ERROR){
cout << "error recv(): " << WSAGetLastError() << endl;
break;}
imshow("image",image);
waitKey(0.1);
}
closesocket(client);
closesocket(slisten);
WSACleanup();
return 0;
}
Client 端代码:
#pragma comment(lib, "ws2_32.lib")
#include <cstdio>
#include <iostream>
#include <WinSock2.h>
#include <Windows.h>
#include<opencv2/opencv.hpp>
using namespace std;
using namespace cv;
char * recvbuf;
int main()
{
// Hilfsvariable
long res;
// Versionsdaten
WSADATA wsaData;
// ws2_32.dll aktivieren
res = WSAStartup(MAKEWORD(2, 1), &wsaData);
if(res == 0 )
cout << "WSAStartup()\t\t successful" << endl;
else
cout << "error WSAStartup(): " << WSAGetLastError() << endl;
// Socket Deskriptoren
SOCKET slisten, client;
// Socket anforder bzw. Kommunikationsendpunkt einrichten
slisten = socket(AF_INET, SOCK_STREAM, 0);
if(slisten != INVALID_SOCKET )
cout << "socket() \t\t successful" << endl;
else
cout << "error socket(): " << WSAGetLastError() << endl;
// Verbindungsinformationen
sockaddr_in info;
// sockaddr
info.sin_addr.s_addr = inet_addr("158.132.8.117");
info.sin_family
= AF_INET;
info.sin_port
= htons(9992);
int infolen = sizeof(info);
res = bind(slisten, (struct sockaddr*)&info, infolen);
if(res != SOCKET_ERROR )
cout << "bind() \t\t successful" << endl;
else
cout << "error bind(): " << WSAGetLastError() << endl;
// Warteschlange f黵 einkommende Verbindungen
res = listen(slisten, SOMAXCONN);
if(res != SOCKET_ERROR )
cout << "listen() \t\t successful" << endl;
else
cout << "error listen(): " << WSAGetLastError() << endl;
sockaddr_in clientinfo;
int clientinfolen = sizeof(clientinfo);
client = accept(slisten, (struct sockaddr*)&clientinfo, &clientinfolen);
if(client != SOCKET_ERROR)
cout << "client accepted: " << inet_ntoa(clientinfo.sin_addr) << ":"
<< ntohs(clientinfo.sin_port) << endl;
while(1)
{
// 黚er das Socket kommunizieren
/*res = send(client, "server message received", strlen("server message received"), 0);
if(res == SOCKET_ERROR)
cout << "error send()" << WSAGetLastError() << endl;*/
res = recv(client, recvbuf, 1000, 0);
uchar* data2;
data2 = (uchar *)recvbuf;
Mat image = Mat(500, 500, CV_8UC3);
image.data = data2;
if(res == SOCKET_ERROR){
cout << "error recv(): " << WSAGetLastError() << endl;
break;}
imshow("image",image);
waitKey(0.1);
}
closesocket(client);
closesocket(slisten);
WSACleanup();
return 0;
}
答案
-
TCP是流,是没有边界的,所以在TCP中您需要知道您的数据什么时候接收完整了。即需要知道发送了多少,就对应的接收多少。 send/recv()这些winsock API最好都判断一下返回值是多少,于您期望的值时候相符。
Visual C++ enthusiast, like network programming and driver development. At present is being engaged in the WinCE/Windows Mobile platform embedded development.
- 已标记为答案 Shu 2017 2015年4月9日 12:40