天天看點

c實作非常簡單的區域網路聊天程式

// Sock.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <stdio.h> 
#include <stdlib.h>
#include <winsock2.h> 
#include <Winsock.h>
#include "sock_define.h"
char m_curchatip[20];
char m_tempchatip[20];
char m_chatcontent[1024];
int firstchar = 0;
#pragma comment(lib, "ws2_32.lib")
void SendMsgByType(const char * pszIP,MSG_HEAD msg_type,const char * pszMsg)
{
 SOCKET sockSrv_chat=socket(AF_INET,SOCK_DGRAM,0);
 sockaddr_in addrSrv_chat;
 addrSrv_chat.sin_addr.s_addr = inet_addr(pszIP);
 addrSrv_chat.sin_family = AF_INET;
 addrSrv_chat.sin_port = htons(PORT);
 
 bool bBroadcast = true;//設定廣播
 setsockopt(sockSrv_chat, SOL_SOCKET, SO_BROADCAST, (const char*)&bBroadcast, sizeof(bool)); 
 
 struct MSG_TYPE package;
 package.type = msg_type;
 memset(package.buf,0,sizeof(package.buf));//
 strncpy(package.buf,pszMsg,sizeof(package.buf));
 sendto(sockSrv_chat,(const char *)(&package),sizeof(package),0,(SOCKADDR*)&addrSrv_chat,sizeof(SOCKADDR));
 // printf("error:%d\n",GetLastError());
 closesocket(sockSrv_chat);
    
}
void detectAllusers()
{
    SendMsgByType(BROADCASTIP,DETECT,"broadcast");
}
void Thread1()//多線程測試 首次發送chat 不起個線程的話receive就不能輸入了
{
//  printf("選擇聊天對象。\n"); 
//  memset(m_curchatip,0,sizeof(m_curchatip));
//  gets(m_curchatip);
//  firstchar += 1;
//  if(strlen(m_tempchatip)>1)
//  {
//   strcpy(m_curchatip,m_tempchatip);
//  }
 while(true)
 {
  //     printf("\n我說:",m_curchatip);
  memset(m_chatcontent,0,sizeof(m_chatcontent));
  // scanf("我說:%s",m_chatcontent);
  gets(m_chatcontent);
  //     int i=0;
  //     while((m_chatcontent[i]=getchar())!=' ') //
  //      i++;
  //     
  //SendMsgByType(m_curchatip,CHAT,m_chatcontent);--BROADCASTIP
  SendMsgByType(BROADCASTIP,CHAT,m_chatcontent);//群聊模式
  
 }
 
}
void Thread2()//多線程測試
{
 
 while(true)
 {
  printf("正在和%s聊天中。\n請輸入内容:",m_curchatip);
  memset(m_chatcontent,0,sizeof(m_chatcontent));
  gets(m_chatcontent);
  SendMsgByType(m_curchatip,CHAT,m_chatcontent);    
 }
 
}
int main(int argc, char* argv[])
{
 m_usecount = 1;
 memset(m_tempchatip,0,sizeof(m_curchatip));
 WSADATA wsa; 
 WORD wVersionRequested; 
 
 wVersionRequested = MAKEWORD(2,2);  
 if (WSAStartup(wVersionRequested , &wsa)!=0) 
 { 
  printf("Winsock Initialization failed.\n"); exit(0); 
 }
 printf("Winsock Initialization sucessed.\n"); 
 
    struct protoent *ppe;
 ppe=getprotobyname("udp");
 SOCKET ListenSocket=socket(AF_INET,SOCK_DGRAM,ppe->p_proto);
 // printf("error:%d\n",GetLastError());
 
 /*Socket(AF_INET, SOCK_STREAM, 0);  //傳回的是一個TCP套接字
 Socket(AF_INET, SOCK_DGRAM, 0);   //傳回的是一個UDP套接字
 */
 
    detectAllusers();
 SOCKET sockSrv=socket(AF_INET,SOCK_DGRAM,0);
 SOCKADDR_IN addrSrv;
 addrSrv.sin_addr.S_un.S_addr=htonl(INADDR_ANY);
 addrSrv.sin_family=AF_INET;
 addrSrv.sin_port=htons(PORT); 
 bind(sockSrv,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR)); 
 SOCKADDR_IN addrClient;
 int len=sizeof(SOCKADDR);
 char recvBuf[1024*10]; 
 
 int PORT_TEST = 6001;
 int iR; 
 DWORD ThreadID; 
 HANDLE hThread1 = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)Thread1, NULL, 0, &ThreadID); 
 iR = SetThreadPriority(hThread1, THREAD_PRIORITY_NORMAL);  
    while(true)
 {
  
  recvfrom(sockSrv,recvBuf,sizeof(recvBuf),0,(SOCKADDR*)&addrClient,&len);
  // printf("error:%d\n",GetLastError());
  struct MSG_TYPE *package= (MSG_TYPE *)recvBuf;
  switch (package->type)
  {
  case DETECT:
   {     
    SendMsgByType(inet_ntoa(addrClient.sin_addr),REDETECT,"redetect");
    printf("%s online.\n",inet_ntoa(addrClient.sin_addr));
    break;
   };
  case REDETECT:
   {
    /// SendMsgByType(inet_ntoa(addrClient.sin_addr),CHART);
    printf("%s online.\n",inet_ntoa(addrClient.sin_addr));
    break;
    
   }
  case CHAT:
   { 
    //SendMsgByType(inet_ntoa(addrClient.sin_addr),CHAT,"chat");
    printf("%s 說: %s\n",inet_ntoa(addrClient.sin_addr),package->buf);
    if(hThread1 != NULL )
    {
     strcpy(m_tempchatip,inet_ntoa(addrClient.sin_addr));
    // if(firstchar == 0)printf("按任意鍵回複\n");
     firstchar ++;
     // SetThreadPriority(hThread1,THREAD_PRIORITY_IDLE);
     //TerminateThread( hThread1, DWORD dwExitCode )
     // CloseHandle(hThread1);
    }
    //     memset(m_curchatip,0,sizeof(m_curchatip));
    //     strcpy(m_curchatip,inet_ntoa(addrClient.sin_addr));
    // 
    //     HANDLE hThread2 = NULL;
    //                 if(hThread2 != NULL)
    //     {
    //      CloseHandle(hThread2);
    //     }
    //      hThread2 = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)Thread2, NULL, 0, &ThreadID); 
    //              iR = SetThreadPriority(hThread1, THREAD_PRIORITY_NORMAL);  
    
    
    break;
   };
   
  }
 }
 
 printf("error:%d\n",GetLastError());
    closesocket(sockSrv);
 TerminateThread( hThread1, ThreadID);
 WSACleanup();
 
 //  struct hostent * h;
 //  
 //  if((h=gethostbyname("10.132.42.234"))==NULL)
 //     {
 //   perror("");
 //   exit(0);
 //  }
 //  printf("host name : %s;\n",h->h_name);
 //  sockaddr_in ina;
 //  ina.sin_addr.s_addr=inet_addr(inet_ntoa(*((struct in_addr *)h->h_addr)));
 // // u_long PASCAL FAR address = ntohl(ina.sin_addr);
 //  printf("IP address : %s\n",inet_ntoa(*((struct in_addr *)h->h_addr)));
 //  printf("IP address : %s\n",inet_ntoa(ina.sin_addr));
 return 0;
}
           

還有個sock_define.h。

#if !defined(__SOCK_DEFINE__)
#define __SOCK_DEFINE__
enum  MSG_HEAD
{
 DETECT = 1,//探測使用者
  REDETECT ,//回複探測使用者
  CHAT ,//聊天
  FILETANS//檔案傳輸,暫時沒用
};
struct MSG_TYPE 
{
 MSG_HEAD type;
 char buf[1024*10];
};
 
int m_usecount;
#define  PORT 6000
#define  BROADCASTIP "255.255.255.255"//廣播位址
#endif