求C语言高手,实现一个简单的TCPIP程序以实现两台计算机之间的聊天通信,

求C语言高手,实现一个简单的TCPIP程序以实现两台计算机之间的聊天通信,,第1张

你上面给出的代码其实就是 MSDN 里面的演示代码,不过不完整,只演示了两个函数的使用,我给你看看我写的 TCP 通讯程序,可以在同一个局域网内的两台不同计算机之间聊天 :

这其实就是某本将网络通雀灶余讯的教程里面的例子,不过是我自己重写了一遍,下面给你代码:

========================

下面是公共代码:

========================

#ifndef __CINITSOCK__H__

#define __CINITSOCK__H__

#include <winsock2.h>

#include <iphlpapi.h>

#pragma comment( lib, "ws2_32.lib" )

#pragma comment( lib, "iphlpapi.lib" )

class CInitSock

{

public:

CInitSock( int nMinorVer = 2, int nMajorVer = 2 )

{

 WSADATA wsData

 WORD wVer = MAKEWORD( nMinorVer, nMajorVer )

 if( 0 != 辩和WSAStartup( wVer, &wsData ) ) exit( 0 )

}

~CInitSock( )

{

 WSACleanup( )

}

}

#endif

========================

下面是客户端的代码 :

=======================

#include "CInitSock.h"

#include <iostream>

using namespace std

CInitSock g_Sock

void main( )

{

SOCKET sockClient = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP )

if( INVALID_SOCKET == sockClient )

return

sockaddr_in sockAddr

sockAddr.sin_family = AF_INET

sockAddr.sin_port = htons( 4567 )

sockAddr.sin_addr.S_un.S_addr = inet_addr( "127.0.0.1" )

if( -1 == connect( sockClient, ( sockaddr* )&sockAddr, sizeof( sockAddr ) ) )

{

cout << "connect failed" << endl

return

}

while( true )

{

char szBuf[ MAX_PATH ]

ZeroMemory( szBuf, sizeof( szBuf ) )

cout << "You Say : "

cin >> szBuf

if( SOCKET_ERROR  == send( sockClient, szBuf, MAX_PATH, 0 ) )

{

 cout << "send failed" << endl

 return

}

int nRecvLen = recv( sockClient, szBuf, MAX_PATH, 0 )

if( nRecvLen > 0 )

{

 // szBuf[ nRecvLen ] = '\0'

 cout << "Service Say : " << szBuf << endl <<顷滚 endl

}

else

{

 cout << "recv failed" << endl

 return

}

}

closesocket( sockClient )

}

======================

下面是服务端的代码:

======================

#include "CInitSock.h"

#include <iostream>

using namespace std

CInitSock g_Sock

void main( )

{

SOCKET sockClient = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP )

if( INVALID_SOCKET == sockClient )

return

sockaddr_in sockAddr

sockAddr.sin_family = AF_INET

sockAddr.sin_port = htons( 4567 )

sockAddr.sin_addr.S_un.S_addr = INADDR_ANY

bind( sockClient, ( sockaddr* )&sockAddr, sizeof( sockAddr ) )

listen( sockClient, SOMAXCONN )

char szBuf[ MAX_PATH ]

sockaddr_in remoteAddr

int nLen = sizeof( sockaddr_in )

SOCKET sock = accept( sockClient, ( sockaddr* )&remoteAddr, &nLen )

while( true )

{

int nRecvLen = recv( sock, szBuf, MAX_PATH, 0 )

if( nRecvLen > 0 )

{

 cout << "Client Say : " << szBuf << endl << endl

}

ZeroMemory( szBuf, sizeof( szBuf ) )

cout << "You Say : "

cin >> szBuf

if( SOCKET_ERROR == send( sock, szBuf, MAX_PATH, 0 ) )

{

 cout << "send failed" << endl

}

}

closesocket( sock )

closesocket( sockClient )

}

希望能够帮到楼主 。

4.1服务器端代码

开启服务器功能:

void OnServerOpen() //开启服务器功能

{

WSADATA wsaData

int iErrorCode

char chInfo[64]

if (WSAStartup(WINSOCK_VERSION, &wsaData)) //调用Windows Sockets DLL

{ MessageBeep(MB_ICONSTOP)

MessageBox("Winsock无法初始化!", AfxGetAppName(), MB_OK|MB_ICONSTOP)

WSACleanup()

return}

else

WSACleanup()

if (gethostname(chInfo, sizeof(chInfo)))

{ ReportWinsockErr("\n无法获取主机!\n ")

return}

CString csWinsockID = "\n==>>服务器功能开启在端口:No. "

csWinsockID += itoa(m_pDoc->m_nServerPort, chInfo, 10)

csWinsockID += "\n"

PrintString(csWinsockID)//在程序视图显示提示信息的函数,读者可自行创建

m_pDoc->m_hServerSocket=socket(PF_INET, SOCK_STREAM, DEFAULT_PROTOCOL)

//御贺嫌创建服务器端Socket,类型为SOCK_STREAM,面向连接镇手的通信

if (m_pDoc->m_hServerSocket == INVALID_SOCKET)

{ ReportWinsockErr("无法创建服务器socket!")

return}

m_pDoc->m_sockServerAddr.sin_family = AF_INET

m_pDoc->m_sockServerAddr.sin_addr.s_addr = INADDR_ANY

m_pDoc->m_sockServerAddr.sin_port = htons(m_pDoc->m_nServerPort)

if (bind(m_pDoc->m_hServerSocket, (LPSOCKADDR)&m_pDoc->m_sockServerAddr,

sizeof(m_pDoc->m_sockServerAddr)) == SOCKET_ERROR) //与选定的端口绑定

{ReportWinsockErr("无法绑定服务器socket!")

return}

iErrorCode=WSAAsyncSelect(m_pDoc->m_hServerSocket,m_hWnd,

WM_SERVER_ACCEPT, FD_ACCEPT)

//设定服务器相应的网络事件为FD_ACCEPT,即连接请求,

// 产生相应传递给窗口的消息为WM_SERVER_ACCEPT

if (iErrorCode == SOCKET_ERROR)

{ ReportWinsockErr("WSAAsyncSelect设定失败!")

return}

if (listen(m_pDoc->m_hServerSocket, QUEUE_SIZE) == SOCKET_ERROR) //开始监听客户连接请求

{ReportWinsockErr("服务器socket监听失败!")

m_pParentMenu->EnableMenuItem(ID_SERVER_OPEN, MF_ENABLED)

return}

m_bServerIsOpen = TRUE//监视服务器是否打开的变拍租量

return

}

响应客户发送聊天文字到服务器:ON_MESSAGE(WM_CLIENT_READ, OnClientRead)

LRESULT OnClientRead(WPARAM wParam, LPARAM lParam)

{

int iRead

int iBufferLength

int iEnd

int iRemainSpace

char chInBuffer[1024]

int i

for(i=0(i

//MAXClient是服务器可响应连接的最大数目

{}

if(i==MAXClient) return 0L

iBufferLength = iRemainSpace = sizeof(chInBuffer)

iEnd = 0

iRemainSpace -= iEnd

iBytesRead = recv(m_aClientSocket[i], (LPSTR)(chInBuffer+iEnd), iSpaceRemaining, NO_FLAGS)

//用可控缓冲接收函数recv()来接收字符

iEnd+=iRead

if (iBytesRead == SOCKET_ERROR)

ReportWinsockErr("recv出错!")

chInBuffer[iEnd] = '\0'

if (lstrlen(chInBuffer) != 0)

{PrintString(chInBuffer)//服务器端文字显示

OnServerBroadcast(chInBuffer)//自己编写的函数,向所有连接的客户广播这个客户的聊天文字

}

return(0L)

}

对于客户断开连接,会产生一个FD_CLOSE消息,只须相应地用closesocket()关闭相应的Socket即可,这个处理比较简单。

4.2客户端代码

连接到服务器:

void OnSocketConnect()

{ WSADATA wsaData

DWORD dwIPAddr

SOCKADDR_IN sockAddr

if(WSAStartup(WINSOCK_VERSION,&wsaData)) //调用Windows Sockets DLL

{MessageBox("Winsock无法初始化!",NULL,MB_OK)

return

}

m_hSocket=socket(PF_INET,SOCK_STREAM,0)//创建面向连接的socket

sockAddr.sin_family=AF_INET//使用TCP/IP协议

sockAddr.sin_port=m_iPort//客户端指定的IP地址

sockAddr.sin_addr.S_un.S_addr=dwIPAddr

int nConnect=connect(m_hSocket,(LPSOCKADDR)&sockAddr,sizeof(sockAddr))//请求连接

if(nConnect)

ReportWinsockErr("连接失败!")

else

MessageBox("连接成功!",NULL,MB_OK)

int iErrorCode=WSAAsyncSelect(m_hSocket,m_hWnd,WM_SOCKET_READ,FD_READ)

//指定响应的事件,为服务器发送来字符

if(iErrorCode==SOCKET_ERROR)

MessageBox("WSAAsyncSelect设定失败!")

}

接收服务器端发送的字符也使用可控缓冲接收函数recv(),客户端聊天的字符发送使用数据可控缓冲发送函数send(),这两个过程比较简单,在此就不加赘述了。


欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/yw/12457370.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-25
下一篇 2023-05-25

发表评论

登录后才能评论

评论列表(0条)

保存