今天突然想写写控制台上的聊天程序,不想使用客户端、服务器模式编写,所以想到了用两个线程来控制。但是只能在自己的本机测试成功。
应该说是离成功还远着了。首先如果实现多机通信,那么我设置的一个接听、一个发送的线程,要怎么样的执行了。那么就设置一个互斥量,让两个进程一个以接受为先进程,另一个以发送为先进程这样他们就能开始通信了。只能一问一答式的进行聊天。这样就有问题了。不能同时实时聊天。还有什么方法能解决这个问题,请高手指点啊。
#include <stdio.h>
#include <Winsock2.h>
//#include <StdAfx.h>
SOCKET sock;
struct SOCKPARAM{
SOCKET m_sock;
};
bool InitSock()
{
sock = socket(AF_INET,SOCK_DGRAM,0);
if(sock == INVALID_SOCKET)
{
printf("Socket Create Failed!/n");
return FALSE;
}
SOCKADDR_IN addrSock;
addrSock.sin_addr.S_un.S_addr = inet_addr("192.168.104.133");
addrSock.sin_family = AF_INET;
addrSock.sin_port = htons(6000);
int retval;
retval = bind(sock,(SOCKADDR*)&addrSock,sizeof(SOCKADDR));
if(retval == SOCKET_ERROR)
{
printf("Socket Bind Failed!/n");
return FALSE;
}
return TRUE;
}
DWORD WINAPI RecvProc(
LPVOID lpParameter);
DWORD WINAPI SendProc(
LPVOID lpParameter);
HANDLE Mutex;
void main()
{
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD( 2, 2 );
err = WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 ) {
return;
}
if ( LOBYTE( wsaData.wVersion ) != 2 ||
HIBYTE( wsaData.wVersion ) != 2 ) {
WSACleanup( );
return;
}
if(FALSE == InitSock())
{
return ;
}
SOCKPARAM * lpParam = new SOCKPARAM;
lpParam->m_sock = sock;
HANDLE Thread1 = CreateThread(NULL,0,RecvProc,(LPVOID)lpParam,0,NULL);
HANDLE Thread2 = CreateThread(NULL,0,SendProc,(LPVOID)lpParam,0,NULL);
CloseHandle(Thread1);
CloseHandle(Thread2);
Mutex = CreateMutex(NULL,FALSE,NULL);
if(Mutex)
{
if(ERROR_ALREADY_EXISTS == GetLastError())
{
printf("only instance can run!");
return ;
}
}
//Sleep(10);
// CreateMutex(
while(1);
return;
}
DWORD WINAPI SendProc(
LPVOID lpParameter)
{
SOCKADDR_IN addrSend;
addrSend.sin_addr.S_un.S_addr = inet_addr("192.168.104.137");
addrSend.sin_family = AF_INET;
addrSend.sin_port = htons(6000);
SOCKET sendsock;
sendsock = ((SOCKPARAM *)lpParameter)->m_sock;
char sendBuf[200];
// memset(sendBuf,NULL,sizeof(sendBuf));
// char tempBuf[300];
while(true)
{
// Sleep(1);
WaitForSingleObject(Mutex,INFINITE);
gets(sendBuf);
sendto(sendsock,sendBuf,strlen(sendBuf)+1,0,(SOCKADDR*)&addrSend,sizeof(SOCKADDR));
ReleaseMutex(Mutex);
}
return 0;
}
DWORD WINAPI RecvProc(
LPVOID lpParameter)
{
SOCKADDR_IN addrRecv;
addrRecv.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
addrRecv.sin_family = AF_INET;
addrRecv.sin_port = htons(6000);
SOCKET recvsock = ((SOCKPARAM *)lpParameter)->m_sock;
int len = sizeof(SOCKADDR);
char recvBuf[200];
char tempBuf[300];
while(true)
{
// Sleep(1);
WaitForSingleObject(Mutex,INFINITE);
recvfrom(recvsock,recvBuf,200,0,(SOCKADDR*)&addrRecv,&len);
sprintf(tempBuf,"%s Says: %s",inet_ntoa(addrRecv.sin_addr),recvBuf);
printf("%s/n",tempBuf);
ReleaseMutex(Mutex);
if(!strcmp(recvBuf,"bye"))
{
exit(0);
}
}
return 0;
}