两台pc机用一个socket通信,每个pc机创建两个线程一个发消息一个收消息 windows socket

来源:互联网 发布:重庆大学网络教育费用 编辑:程序博客网 时间:2024/05/09 20:47

//pc1
#include <stdio.h>
#include <Winsock2.h>
#pragma comment(lib, "ws2_32.lib")

HANDLE xinhao;
SOCKET sockConn;
DWORD WINAPI RecvProc(LPVOID lpParameter);
DWORD WINAPI ServerProc(LPVOID lpParameter);

void main(void)
{
HANDLE serverThread,recvThread;
xinhao=CreateSemaphore(NULL,1,1,NULL);
recvThread=CreateThread( NULL,0,RecvProc,NULL, 0,NULL); 
serverThread=CreateThread( NULL,0,ServerProc,NULL, 0,NULL);  

WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD(2, 0);

err = WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 )  
{
return ;
}
if ( LOBYTE( wsaData.wVersion ) !=2 ||HIBYTE( wsaData.wVersion ) != 0 )  
{
WSACleanup( );
return ;
}

SOCKET sockSrv=socket(AF_INET,SOCK_STREAM,0);

SOCKADDR_IN addrSrv;
addrSrv.sin_addr.S_un.S_addr=htonl(INADDR_ANY);
addrSrv.sin_family=AF_INET;
addrSrv.sin_port=htons(6000);

bind(sockSrv,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));// 绑定端口

listen(sockSrv,10);

SOCKADDR_IN addrClient;// 连接上的客户端ip地址
int len=sizeof(SOCKADDR);

SOCKET sockConn=accept(sockSrv,(SOCKADDR*)&addrClient,&len); // 接受客户端连接,获取客户端的ip地址

// Sleep(5000);
// Sleep(5000);

CloseHandle(serverThread);
CloseHandle(recvThread);
CloseHandle(xinhao);

closesocket(sockConn);
WSACleanup();   
getchar();
return ;
}

DWORD WINAPI RecvProc(LPVOID lpParameter)
{
char recvBuf[100];
while(1)
{
recv(sockConn,recvBuf,100,0);
printf("%s\n",recvBuf);
memset(recvBuf,0x20,100);
ReleaseSemaphore(xinhao,1,NULL);
}
return 0;
}

DWORD WINAPI ServerProc(LPVOID lpParameter)
{
char sendBuf[100]="发送到pc2";
while(1)
{
WaitForSingleObject(xinhao,INFINITE);
send(sockConn,sendBuf,strlen(sendBuf)+1,0);
}
return 0;
}

//pc2
#include <stdio.h>
#include <Winsock2.h>
#pragma comment(lib, "ws2_32.lib")

HANDLE xinhao;
DWORD WINAPI RecvProc(LPVOID lpParameter);
DWORD WINAPI ServerProc(LPVOID lpParameter);
SOCKET sockClient;

void main(void)
{
HANDLE serverThread,recvThread;

xinhao=CreateSemaphore(NULL,1,1,NULL);
serverThread=CreateThread( NULL,0,ServerProc,NULL,0,NULL);  
recvThread=CreateThread( NULL,0,RecvProc,NULL, 0,NULL);  

WORD wVersionRequested;
WSADATA wsaData;
int err;

wVersionRequested = MAKEWORD( 2, 0 );

err = WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 )  
{
return ;
}
if ( LOBYTE( wsaData.wVersion ) !=2 ||HIBYTE( wsaData.wVersion ) != 0 )  
{
WSACleanup();
return ;
}

SOCKET sockClient=socket(AF_INET,SOCK_STREAM,0);

SOCKADDR_IN addrSrv;
addrSrv.sin_addr.S_un.S_addr=inet_addr("127.0.0.1");
addrSrv.sin_family=AF_INET;
addrSrv.sin_port=htons(6000);

connect(sockClient,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR_IN));

// Sleep(5000);
// Sleep(5000);

CloseHandle(serverThread);
CloseHandle(recvThread);
CloseHandle(xinhao);

closesocket(sockClient);
WSACleanup();   
getchar();
return ;
}

DWORD WINAPI ServerProc(LPVOID lpParameter)
{
char sendBuf[100]="发送到pc1";
while(1)
{
WaitForSingleObject(xinhao,INFINITE);
send(sockClient,sendBuf,strlen(sendBuf)+1,0);
}  
return 0;
}

DWORD WINAPI RecvProc(LPVOID lpParameter)

{
char recvBuf[100];
while(1)
{
recv(sockClient,recvBuf,100,0);
printf("%s\n",recvBuf);
ReleaseSemaphore(xinhao,1,NULL);
memset(recvBuf,0x20,100);
}
return 0;
}

------解决方案--------------------
要在accept成功后才能recv
你一开始就创建线程recv,都还没accept,还有WSAStartup可能都没执行完
recv肯定失败了 
------解决方案--------------------
在你的全局定义中SOCKET sockConn;改成SOCKET sockConn=NULL;
在你的代码中,SOCKET sockConn=accept(sockSrv,(SOCKADDR*)&addrClient,&len); // 接受客户端连接,获取客户端的ip地址
sockConn再次定义了,此时全局的sockConn被覆盖了,你accept得到的客户端线程无法使用
在两个子线程的while中添加
Sleep(1); //释放系统控制权,以免CPU占用率100%
if(sockConn==NULL)  
{
continue;
}

0 0
原创粉丝点击