我用socket2的API写了服务器和客户端,客户端连两个时,前面一个就不能正常工作(好像是被阻塞了)
VC代码见http://www4.7show.net/luck8888/sck
麻烦加上“.rar”--------------------------
特向高手请教,接受socket,拒绝MFC
--------------------------附:client端代码
#include <stdio.h>
#include <winsock2.h>void main()
{
WSADATA wsaData;
SOCKET clientSocket;
int err;
//WSAStartup
if(WSAStartup(0x0202, &wsaData)!=0)
{
err=WSAGetLastError();
printf("无法使用Socket库,错误代码:%d\n",err);
return;
} //socket
clientSocket = socket(AF_INET, SOCK_STREAM, 0);
if(clientSocket == SOCKET_ERROR)
{
printf("建立socket失败\n");
return;
} struct sockaddr_in serverAddr; //连接服务器
serverAddr.sin_family = AF_INET;
serverAddr.sin_addr.s_addr = inet_addr("127.0.0.1"); //htonl(INADDR_ANY);
serverAddr.sin_port=htons(8001);
memset(serverAddr.sin_zero,0,8); clientSocket = socket(AF_INET, SOCK_STREAM, 0); if(connect(clientSocket, (struct sockaddr *)&serverAddr, sizeof(struct sockaddr)) == SOCKET_ERROR)
{
printf("connect错误,错误代码:%d",WSAGetLastError());
closesocket(clientSocket);
WSACleanup();
exit(1);
}
char msg[256];
int bQuit=0;
int nRet;
while(!bQuit)
{
gets(msg);
if(strcmp(msg,"quit")==0) bQuit=1; //发送数据
nRet = send(clientSocket, msg, strlen(msg), 0);
if(nRet == SOCKET_ERROR)
{
printf("send错误,错误代码:%d",WSAGetLastError());
continue;
} //接收数据
char buf[256]; ///////////////////////////////////// printf("准备接收...\n");
nRet = recv(clientSocket, buf, 255, 0);
if(nRet > 0)
{
buf[nRet] = 0;
printf("\n收到的回复为:%s",buf);
}
else
{
printf("\nrecv error: %d\n", nRet);
} } shutdown(clientSocket, SD_RECEIVE);
closesocket(clientSocket);
WSACleanup();}
VC代码见http://www4.7show.net/luck8888/sck
麻烦加上“.rar”--------------------------
特向高手请教,接受socket,拒绝MFC
--------------------------附:client端代码
#include <stdio.h>
#include <winsock2.h>void main()
{
WSADATA wsaData;
SOCKET clientSocket;
int err;
//WSAStartup
if(WSAStartup(0x0202, &wsaData)!=0)
{
err=WSAGetLastError();
printf("无法使用Socket库,错误代码:%d\n",err);
return;
} //socket
clientSocket = socket(AF_INET, SOCK_STREAM, 0);
if(clientSocket == SOCKET_ERROR)
{
printf("建立socket失败\n");
return;
} struct sockaddr_in serverAddr; //连接服务器
serverAddr.sin_family = AF_INET;
serverAddr.sin_addr.s_addr = inet_addr("127.0.0.1"); //htonl(INADDR_ANY);
serverAddr.sin_port=htons(8001);
memset(serverAddr.sin_zero,0,8); clientSocket = socket(AF_INET, SOCK_STREAM, 0); if(connect(clientSocket, (struct sockaddr *)&serverAddr, sizeof(struct sockaddr)) == SOCKET_ERROR)
{
printf("connect错误,错误代码:%d",WSAGetLastError());
closesocket(clientSocket);
WSACleanup();
exit(1);
}
char msg[256];
int bQuit=0;
int nRet;
while(!bQuit)
{
gets(msg);
if(strcmp(msg,"quit")==0) bQuit=1; //发送数据
nRet = send(clientSocket, msg, strlen(msg), 0);
if(nRet == SOCKET_ERROR)
{
printf("send错误,错误代码:%d",WSAGetLastError());
continue;
} //接收数据
char buf[256]; ///////////////////////////////////// printf("准备接收...\n");
nRet = recv(clientSocket, buf, 255, 0);
if(nRet > 0)
{
buf[nRet] = 0;
printf("\n收到的回复为:%s",buf);
}
else
{
printf("\nrecv error: %d\n", nRet);
} } shutdown(clientSocket, SD_RECEIVE);
closesocket(clientSocket);
WSACleanup();}
----------------------------------------
sClient = accept(listenSocket, (struct sockaddr *)&clientAddr, &nAddrLen); if(sClient == SOCKET_ERROR)
{
err = WSAGetLastError();
printf("\naccept错误,错误代码:%d\n",err);
return;
}
else
{
printf("接受来自%s的连接请求\n",inet_ntoa(clientAddr.sin_addr)); //建立一个线程处理请求
static PARAMS params;
//线程处理函数的参数
params.IP = clientAddr.sin_addr;
params.port = clientAddr.sin_port;
params.s = sClient; HANDLE hThread=(void *)_beginthread(ThreadFunc,0,(void *)¶ms);
CloseHandle(hThread);
--------------------------------------
这是线程处理函数
--------------------------------------
void ThreadFunc(void *pvoid)
{
PARAMS *pParams; pParams = (PARAMS *) pvoid ; printf("连接上%s:%u socket=0x%X\n", inet_ntoa(pParams->IP), ntohs(pParams->port), pParams->s);
int nRet;
char buf[256]; while(1)
{
printf("socket=0x%X\n", pParams->s); //在接收数据前,可以另开一个线程来处理超时
nRet = recv(pParams->s, buf, 255, 0); if(nRet > 0)
{
buf[nRet] = 0;
printf("收到的信息为:%s",buf);
}
else
{
printf("recv error: %d\n", nRet);
break;
}
//printf("\n接收完毕!\n");
//收到停止服务命令
if(strcmp(buf,"stop")==0)
{
closesocket(pParams->s);
closesocket(listenSocket);
WSACleanup();
printf("server stopped by admin.\n");
_endthread();
}
//发回到客户端
Sleep(20);
printf("\n开始回复客户端...");
strcpy(buf,"消息已收到\n");
nRet = send(pParams->s,buf,strlen(buf),0); if(nRet > 0)
{
buf[nRet] = 0;
printf("回复成功\n---------------------------\n");
}
else
{
printf("\nsend error: %d\n", nRet);
break;
} }
closesocket(pParams->s);
printf("断开%s:%u socket=0x%X\n", inet_ntoa(pParams->IP), ntohs(pParams->port), pParams->s);}
static PARAMS params;//线程处理函数的参数
params.IP = clientAddr.sin_addr;
params.port = clientAddr.sin_port;
params.s = sClient;HANDLE hThread=(void *)_beginthread(ThreadFunc,0,(void *)¶ms);
CloseHandle(hThread);你定义的params是用于存储IP/Port/Sock信息的,但是无论连入了多少个客户端,你好像都只有这样一个变量,那么这个结构里就只能保存下最后一个的信息了,包括Soctet在内,之前的都被丢失了。
把params定义成数组吧,或者把结构修改成链表形式的,要确保每一个Socket有一个单独的变量。
{
err = WSAGetLastError();
printf("\naccept错误,错误代码:%d\n",err);
return;
}
else
{
printf("接受来自%s的连接请求\n",inet_ntoa(clientAddr.sin_addr)); //建立一个线程处理请求
static PARAMS params;
//线程处理函数的参数
params.IP = clientAddr.sin_addr;
params.port = clientAddr.sin_port;
params.s = sClient; HANDLE hThread=(void *)_beginthread(ThreadFunc,0,(void *)¶ms);
CloseHandle(hThread);
============================================================================
这里是否为一个循环??? 如果否那么就只能一个CLIENT连接进来了!!
{
sClient = accept(listenSocket, (struct sockaddr *)&clientAddr, &nAddrLen)
.............
...........
} 加循环就可以了
贴出之后我也发现了这个问题,就是static变量的问题,多线程是共用的,而我只是传了一个指针给ThreadFunc,每次都改为最后一个socket的ID
我的修改如下:
PARAMS tmpParams;
memcpy(&tmpParams,pvoid,sizeof(PARAMS));
每个线程拷贝一份就好了