既是服务器端又是客户端,由孙鑫15课的那个对话框聊天程序改编。不同的是我这个用API/SDK,并且是TCP的
#define WM_RECVDATA WM_USER+1    //自定义消息
char* Add(char* str1,char* str2)  //C语言实现CString的+操作符功能

char* buf = (char*)malloc(strlen(str1) + strlen(str2) + 1); 
sprintf(buf,"%s",str1); 
strcat(buf,str2); 
return buf; 
}
BOOL CALLBACK ChatDlgProc(HWND hwndDlg,UINT uMsg,WPARAM wParam,LPARAM lParam)
{
WORD wVersionRequested;
WSADATA wsaData;
static SOCKET m_socket,m_sockClient;
static SOCKADDR_IN addrSock,addrTo;
int retval;
RECVPARAM *pRecvParam = NULL;
static DWORD dwIP = 0 ;
static HWND hwndIP;
char *str = NULL;
HANDLE hThread = NULL;
int textSendLen =0;
int textRecvLen =0;
char *strSend = NULL; 
char *strTemp = NULL;
char *strBuf = NULL;
static HWND hwndEditSend ;
static HWND hwndEditRecv ;
int len = sizeof(SOCKADDR) ;
switch(uMsg)
{
case WM_INITDIALOG:
 hwndEditRecv = GetDlgItem(hwndDlg,IDC_EDIT_RECV) ;     //显示聊天记录的编辑框
 hwndIP = GetDlgItem(hwndDlg,IDC_IPADDRESS1);    //对话框IP控件
 return TRUE;
case WM_RECVDATA:
 str=(char*)lParam;    //自定义消息的lParam是接收到的聊天记录
 textRecvLen = GetWindowTextLength(hwndEditRecv);
 strTemp = (char*)malloc(textRecvLen+1);
 GetDlgItemText(hwndDlg,IDC_EDIT_RECV,strTemp,textRecvLen+1);
 str = Add(str,"\r\n");
 str = Add(str,strTemp);
 SetDlgItemText(hwndDlg,IDC_EDIT_RECV,str);
 free(strTemp);
 return TRUE;
case WM_COMMAND:
 switch (LOWORD (wParam))
 {
 case IDC_BTN_CONNECT:
  hwndEditSend = GetDlgItem(hwndDlg,IDC_EDIT_SEND) ;
  SendMessage(hwndIP,IPM_GETADDRESS, 0, (LPARAM) &dwIP);//获取IP地址控件的值
  if(0 != dwIP)
  {
  wVersionRequested = MAKEWORD( 2, 2 );
  WSAStartup( wVersionRequested, &wsaData );
  m_socket = socket (AF_INET, SOCK_STREAM, 0) ;//for TCP
  addrSock.sin_family=AF_INET;
  addrSock.sin_port=htons(6000);
  addrSock.sin_addr.S_un.S_addr=htonl(INADDR_ANY);
  retval=bind(m_socket,(SOCKADDR*)&addrSock,sizeof(SOCKADDR));
  m_sockClient = socket(AF_INET, SOCK_STREAM, 0);
  connect(m_sockClient, (SOCKADDR *)&addrTo, sizeof(SOCKADDR));
  pRecvParam=(RECVPARAM*)malloc(sizeof(RECVPARAM));
  pRecvParam->sock=m_socket;
  pRecvParam->hwnd=hwndDlg;
  hThread=CreateThread(NULL,0,RecvProc,(LPVOID)pRecvParam,0,NULL);
  CloseHandle(hThread);  
  }
  return TRUE;
 case IDC_BTN_SEND:
  addrTo.sin_family=AF_INET;
  addrTo.sin_port=htons(6000);
  addrTo.sin_addr.S_un.S_addr=htonl(dwIP);
  textSendLen = GetWindowTextLength(hwndEditSend);
  strSend = (char*)malloc(textSendLen+1);
  GetDlgItemText(hwndDlg,IDC_EDIT_SEND,strSend,textSendLen+1);
  send(m_sockClient,strSend,strlen(strSend)+1,0);//for TCP
  SetDlgItemText(hwndDlg,IDC_EDIT_SEND,"");
  return TRUE;
 }
 break;
case WM_CLOSE:
 DestroyWindow(hwndDlg);
 hChatDlg = NULL;
 break;
}
return FALSE;
}DWORD WINAPI RecvProc(LPVOID lpParameter)
{
static SOCKADDR_IN addrFrom;
static SOCKET sockConn;
int retval;
SOCKET sock;
HWND hwnd;
int len;
         char recvBuf[200];
char tempBuf[300];
sock=((RECVPARAM*)lpParameter)->sock;
hwnd=((RECVPARAM*)lpParameter)->hwnd;
free(lpParameter);
len=sizeof(SOCKADDR);
listen(sock,5);
sockConn = accept(sock,(SOCKADDR*)&addrFrom,&len);//调试运行到这,sockConn的值为0,accept不返回了
while(TRUE)
{
connect(sock,(SOCKADDR*)&addrFrom,sizeof(SOCKADDR));
retval=recv(sock,recvBuf,200,0);
if(SOCKET_ERROR==retval)
break;
sprintf(tempBuf,"%s说: %s",inet_ntoa(addrFrom.sin_addr),recvBuf);
PostMessage(hwnd,WM_RECVDATA,(WPARAM)0,(LPARAM)tempBuf);
}
return 0;
}
IP地址输入的是127.0.0.1
我把listen和accept,connect这些去掉,send/recv换成sendto/recvfrom,它能以UDP模式运作聊天
换成TCP后,插断点调试运行到accept时,单步运行不下去了。直接运行后效果是无法通信。