我在互联网上找到了一些关于在C ++中创建TCP / IP服务器的基础知识。 我拿了这段代码,添加了一些库和一些代码行。结果是,我能够在Windows上的Qt Creator中编译和运行代码/服务器作为控制台程序。然而,我无法连接到服务器,因为它只是运行代码而无需等待并接受来自TCP客户端的连接。
这是代码: 编辑:代码已更新,现在正在运行。测试== -1是解决方案。
#define PORT 2000
#define MAX_QUEUE 5
#define BUF_SIZE 1024
int main(int argc, char* const argv[])
{
cout << "Hello World!" << endl;
WSADATA wsaData;
int wsaret = WSAStartup(MAKEWORD( 4, 4 ), &wsaData);
cout << "wsaret: " << wsaret << endl;
cout << "Start TCP/IP Server" << endl;
/* file descriptors for sockets */
SOCKET sock_1, sock_2; //switched from in to SOCKET //unsigned int sock_1, sock_2;
int rec_value, length;
char buf[BUF_SIZE];
//struct sockaddr_in server;
struct sockaddr_in server;
/* create stream socket in internet domain*/
sock_1 = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
//if(sock_1 < 0)
if(sock_1 == -1)
{
cout << "socket: " << WSAGetLastError() << endl; //instead of //cout << "socket: " << strerror(errno) << endl; //cout << "socket wsaret: " << wsaret << endl;
exit(1);
}
/* build address in internet domain */
server.sin_family = AF_INET;
/* everyone is allowed to connet to server */
server.sin_addr.s_addr = INADDR_ANY; //inet_addr("192.168.145.129");
server.sin_port = htons(2000); //server.sin_port = PORT; //Port: 2000
/* bind socket */
//if(bind(sock_1, (struct sockaddr *)&server, sizeof(server)));
int bindreturn = (bind(sock_1, (struct sockaddr *)&server, sizeof(server)));
if(bindreturn == -1)
{
cout << "bind: " << WSAGetLastError() << endl; //instead of //cout << "bind: " << strerror(errno) << endl; //cout << "bind wsaret: " << wsaret << endl;
exit(1);
}
listen(sock_1,MAX_QUEUE);
/* start accepting connection */
sock_2 = accept(sock_1,0,0);
if(sock_2 < 0)
{
cout << "accept: " << WSAGetLastError() << endl;
exit(1);
}
/* read from sock_2 */
while(rec_value=recv(sock_2,buf,BUF_SIZE,0))
{
if(rec_value < 0)
{
cout << "recv: " << WSAGetLastError() << endl;
exit(1);
}
else
{
cout << "else" << endl;
send(sock_2,"1,2,3",strlen("1,2,3"),0);
}
}
cout << "Ending connection" << endl;
closesocket(sock_1);
closesocket(sock_2);
cout << "End TCP/IP Server" << endl;
WSACleanup();
return 0;
}
控制台在一秒或几秒钟内运行程序后显示以下内容:
Hello World!
wsaret: 0
Start TCP/IP Server
bind: 0
我该怎么做,服务器等待连接伙伴?
提前致谢。
此致 MATL
编辑:在开头添加了几行代码,我以前忘了。 编辑:代码更新 编辑:代码更新
答案 0 :(得分:3)
我将详细评论您发布的原始代码。
cout << "Start TCP/IP Server" << endl;
//int sock_1,sock_2; /* file descriptors for sockets */
int sock_1, sock_2;
int rec_value, length;
char buf[BUF_SIZE];
//struct sockaddr_in server;
sockaddr_in server;
/* create stream socket in internet domain*/
sock_1 = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);//0);
这里缺少测试。您必须在以下行中测试结果-1:
if (sock_1 == -1)
{
cout << "socket creation error: " << WSAGetLastError() << endl;
exit(1); // or some other measure to prevent continuation
}
返回您的代码:
/* build address in internet domain */
server.sin_family = AF_INET;
/* everyone is allowed to connet to server */
server.sin_addr.s_addr = INADDR_ANY; //inet_addr("192.168.145.129");
server.sin_port = PORT; //Port: 2000
那应该是
server.sin_port = htons(PORT);
返回您的代码:
/* bind socket */
int bindreturn = bind(sock_1, (struct sockaddr *)&server, sizeof(server));
cout << "bindreturn: " << bindreturn << endl;
不足。在这里,你需要再次测试-1,然后打印WSAGetLastError()
并在你得到它时退出。
listen(sock_1,MAX_QUEUE);
未测试。在这里你需要测试-1等。
/* start accepting connection */
//system("pause");
sock_2 =accept(sock_1,0,0);
//system("pause");
cout << "acceptreturn: " << sock_2 << endl;
再次不足,见上文。
/* read from sock_2 */
while(rec_value=recv(sock_2,buf,BUF_SIZE,0))
{
if(rec_value<0)
{
cout << "error: " << rec_value << endl;
exit(1);
}
测试不正确。系统调用通过精确返回-1来指示错误,而不仅仅是任何值&lt; 0.例如socket()
或accept()
返回的套接字FD可以是负数,也可以是-1以外的任何值。
else
{
cout << "else" << endl;
send(sock_2,"1,2,3",strlen("1,2,3"),0);
}
}
closesocket(sock_1);
closesocket(sock_2);
cout << "End TCP/IP Server" << endl;
return 0;
从closesocket()
调用显而易见,您正在使用Winsock,在这种情况下,WSAStart()
和WSACleanup()
都会丢失。
答案 1 :(得分:2)
如何定义PORT
?
您应该使用:
server.sin_port = htons(PORT); //Port: 2000
您的IP地址是否正确?
您的所有来电都在接收SOCKET_ERROR
( - 1),因此您应该检查lasterror以获取更多信息。
不确定(在Windows上这里),但不应该是unsigned int
&#39>?
int sock_1, sock_2;
<强>更新强>:
好的,你似乎在Windows上使用Qt。
对于Qt,您也可以使用Qt libraries。
在Windows上,您可以使用免费的MS Visual Studio。
您还需要像这样致电WSAStartup()
:
WSADATA wsaData;
int wsaret = WSAStartup(MAKEWORD( 4, 4 ), &wsaData);
// check wsaret
// more code here
WSACleanup();
还可以使用SOCKET
:
SOCKET sock_1, sock_2;
使用WSAGetLastError()
检查错误代码。