【发布时间】:2015-05-13 15:20:22
【问题描述】:
我有 2 个简单的应用程序,一个客户端和一个服务器。客户端连接到服务器,服务器向客户端发送数据。在客户端应用程序的主循环中,每次我想接收另一条信息时,我都会关闭套接字并创建一个新的。它有效,但对我来说看起来不正确。这是正确的吗?我真的需要每次都关闭并重新打开一个套接字,还是有其他方法可以做到这一点?
客户:
int main(){
DWORD id;
SOCKET s;
struct sockaddr_in sa;
WSADATA wsas;
WORD wersja;
int recv_size;
LPTHREAD_START_ROUTINE WINAPI funkcja = getCommend;
watek = CreateThread(NULL, 0, funkcja, 0, 0, &id);
wersja = MAKEWORD(2, 0);
WSAStartup(wersja, &wsas);
memset((void *)(&sa), 0, sizeof(sa));
sa.sin_family = AF_INET;
sa.sin_port = htons(PORT);
sa.sin_addr.s_addr = inet_addr("25.62.229.110");
int result;
s = socket(AF_INET, SOCK_STREAM, 0);
result = connect(s, (struct sockaddr FAR *) &sa, sizeof(sa));
if (result == SOCKET_ERROR)
{
printf("\nBłąd połączenia!");
return 1;
}
int a;
if ((recv_size = recv(s, server_reply, SIZE, 0)) == SOCKET_ERROR)
{
printf("recv failed\n");
}
else{
while (result != SOCKET_ERROR){
//printf("%s\n", server_reply);
closesocket(s);
Sleep(1000);
s = socket(AF_INET, SOCK_STREAM, 0);
result = connect(s, (struct sockaddr FAR *) &sa, sizeof(sa));
if (result == SOCKET_ERROR){
break;
}
result = recv_size = recv(s, server_reply, SIZE, 0);
}
}
getchar();
closesocket(s);
TerminateThread(watek, NULL);
WSACleanup();
return 1;
}
服务器:
int main(){
DWORD id;
SOCKET s, new_socket;
LPTHREAD_START_ROUTINE WINAPI funkcja = getCommend;
struct sockaddr_in sa, sc;
WSADATA wsas;
int c;
watek = CreateThread(NULL,0,funkcja,0,0,&id);
WSAStartup(MAKEWORD(1, 1), &wsas);
s = socket(AF_INET, SOCK_STREAM, 0);
//memset((void *)(&sa), 0, sizeof(sa));
sa.sin_family = AF_INET;
sa.sin_port = htons(PORT);
sa.sin_addr.s_addr = htonl(INADDR_ANY);
bind(s, (struct sockaddr FAR*)&sa, sizeof(sa));
listen(s, 5);
puts("Czekam na polaczenie...");
c = sizeof(struct sockaddr_in);
while ((new_socket = accept(s, (struct sockaddr *)&sc, &c)) != INVALID_SOCKET)
{
//puts("polaczenie zaakceptowane");
send(new_socket, message, strlen(message), 0);
}
if (new_socket == INVALID_SOCKET)
{
printf("Nie udane połaczenie, blad nr : %d", WSAGetLastError());
return 1;
}
TerminateThread(watek, NULL);
getchar();
}
【问题讨论】:
-
呃……你不关闭socket继续使用?
-
"closesocket(s);"嗯?
-
我说更好的方法是:不要关闭套接字并继续使用它。是什么让您认为您需要关闭套接字?即使在接收到一组数据后,它与服务器的连接也会保持。每次成功调用 recv() 后没有理由关闭它。
-
你的两个代码都错了,但主要是你的服务器。您的服务器在发送新消息之前接受新连接,并且不会关闭先前的连接。因此,您的客户端每次都必须重新连接。您需要更改双方以重用他们已经拥有的现有连接。而且您需要对消息进行框架化,以便客户端知道一条消息在哪里结束以及下一条消息从哪里开始。您不能假设在 TCP 中
send()和recv()之间存在一对一的关系,只能在 UDP 中。