C++|C++ 网络套接字编程TCP和UDP实例

1. 创建一个简单的SOCKET编程流程如下 面向有连接的套接字编程 服务器: 1) 创建套接字(socket) 2) 将套接字绑定到一个本地地址和端口上(bind) 3) 将套接字设定为监听模式,准备接受客户端


1. 创建一个简单的SOCKET编程流程如下
面向有连接的套接字编程
服务器:
1)创建套接字(socket)
2)将套接字绑定到一个本地地址和端口上(bind)
3)将套接字设定为监听模式,准备接受客户端请求(listen)
4)等待客户端请求到来,当请求到来后,接受连接请求,返回一个新的对应于此连接的套接字(accept)
5)用返回的套接字和客户端进行通信(send/recv);
6)返回,等待另一个客户端请求
7)关闭套接字
客户端:
1)创建套接字(socket)
2)向服务器发出连接请求(connect)
3)和服务器进行通信(send/recv)
4)关闭套接字

面向无连接的套接字编程
服务器:(接收端)
1)创建套接字(socket)
2)将套接字绑定到一个本地地址和端口上(bind)
3)用返回的套接字和客户端进行通信(recvfrom);
4)关闭套接字
客户端:(发送端)
1)创建套接字(socket)
2)向服务器发送数据(sendto
3)关闭套接字

例如:面向有连接的套接字编程
首先在工程-à设置àlink 在对象库模板最后面再加上ws2_32.lib
客户端:
#include
#include
int main()
{

//第一步:加载socket库函数
//**********************************************************
WORD wVersionRequested;
WSADATA wsaData;
int err;

wVersionRequested = MAKEWORD( 1, 1 );

err = WSAStartup( wVersionRequested, &wsaData );

if ( err != 0 )
{
return 0;
}

if ( LOBYTE( wsaData.wVersion ) != 1 || HIBYTE( wsaData.wVersion ) != 1 )
{
WSACleanup( );
return 0;
}
//**********************************************************
//第一步,创建套接字
SOCKET sockClient = socket(AF_INET,SOCK_STREAM,0) ;

//定义套接字地址
SOCKADDR_IN addrSrv;
addrSrv.sin_addr.S_un.S_addr=inet_addr("127.0.0.1"); //获取服务器IP地址,inet_addr()将IP地址转为点分十进制的格式

addrSrv.sin_family = AF_INET;
//sin_family 表示地址族,对于IP地址,sin_family成员将一直是AF_INET

addrSrv.sin_port = htons(1234);

//连接服务器
//connect(sockClient,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));

if(connect(sockClient,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR))!=0)
{
//MessageBox("连接失败");
//return;
printf("error");
return 0;
}else
{
printf("success");
}

char recvBuf[100];
recv(sockClient,recvBuf,100,0);
printf("客户端接收到的数据:%s",recvBuf);
send(sockClient,"client send ",strlen("client send ")+1,0);
//关闭套接字
closesocket(sockClient);
//清除套接字资源
WSACleanup();
return 0;
}


服务器端:
#include
#include
int main()
{

//第一步:加载socket库函数
//**********************************************************
WORD wVersionRequested;
WSADATA wsaData;
int err;

wVersionRequested = MAKEWORD( 1, 1 );

err = WSAStartup( wVersionRequested, &wsaData );

if ( err != 0 ) {
return 0;
}

if ( LOBYTE( wsaData.wVersion ) != 1 ||
HIBYTE( wsaData.wVersion ) != 1 ) {
WSACleanup( );
return 0;
}
//**********************************************************

//第二步创建套接字
SOCKET sockSrv = socket(AF_INET,SOCK_STREAM,0);

//第三步:绑定套接字

//获取地址结构
SOCKADDR_IN addrSrv;

addrSrv.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
//将IP地址指定为INADDR_ANY,允许套接字向任何分配给本地机器的IP地址发送或接收数据
//htonl()将主机的无符号长整形数转换成网络字节顺序。

addrSrv.sin_family = AF_INET;
//sin_family 表示地址族,对于IP地址,sin_family成员将一直是AF_INET


addrSrv.sin_port = htons(6000);
//htons()将主机的无符号短整形数转换成网络字节顺序

bind(sockSrv,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));

//监听客户端
listen(sockSrv,5);

//定义从客户端接受的地址信息
SOCKADDR_IN addrClient ;
int len = sizeof(SOCKADDR);

while(1)
{
//不断等待客户端的请求的到来,并接受客户端的连接请求
printf("等待客户连接\n");
SOCKET sockConn = accept(sockSrv,(SOCKADDR*)&addrClient,&len);
char sendBuf[100];
sprintf(sendBuf,"welcome %s to wuhan",inet_ntoa(addrClient.sin_addr));
printf("发送数据\n");
send(sockConn,sendBuf,strlen(sendBuf)+1,0);
char recvBuf[100];
printf("等待接受数据\n");
recv(sockConn,recvBuf,100,0);
printf("%s\n",recvBuf);
closesocket(sockConn);

}
WSACleanup();

return 0;
}


面向无连接的套接字编程
例子:
客户端:

#include "Winsock2.h"
#pragma comment(lib,"ws2_32.lib")
#include "stdio.h"

int _tmain(int argc, _TCHAR* argv[])
{
//第一步:加载socket库函数
//**********************************************************
WORD wVersionRequested;
WSADATA wsaData;
int err;

wVersionRequested = MAKEWORD( 1, 1 );

err = WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 ) {
return 0;
}

if ( LOBYTE( wsaData.wVersion ) != 1 ||
HIBYTE( wsaData.wVersion ) != 1 ) {
WSACleanup( );
return 0;
}

//创建套接字
SOCKET sockClient = socket(AF_INET,SOCK_DGRAM,0);
SOCKADDR_IN sockSrv;
sockSrv.sin_addr.S_un.S_addr=inet_addr("127.0.0.1");
sockSrv.sin_family = AF_INET ;
sockSrv.sin_port = htons(6000);

sendto(sockClient,"hello",strlen("hello")+1,0,(SOCKADDR*)&sockSrv,sizeof(SOCKADDR));
closesocket(sockClient);
WSACleanup();
return 0;
}



服务器:

#include "Winsock2.h"
#pragma comment(lib,"ws2_32.lib")

#include "stdio.h"

int _tmain(int argc, _TCHAR* argv[])
{
//第一步:加载socket库函数
//**********************************************************
WORD wVersionRequested;
WSADATA wsaData;
int err;

wVersionRequested = MAKEWORD( 1, 1 );

err = WSAStartup( wVersionRequested, &wsaData );

if ( err != 0 ) {
return 0;
}

if ( LOBYTE( wsaData.wVersion ) != 1 ||
HIBYTE( wsaData.wVersion ) != 1 ) {
WSACleanup( );
return 0;
}

//创建套接字
SOCKET sockSrv = socket(AF_INET,SOCK_DGRAM,0);
SOCKADDR_IN addSrv;
addSrv.sin_addr.S_un.S_addr=inet_addr("127.0.0.1");
addSrv.sin_family = AF_INET ;
addSrv.sin_port = htons(6000);

bind(sockSrv,(SOCKADDR*)&addSrv,sizeof(SOCKADDR));

SOCKADDR_IN addrClient;
int len = sizeof(SOCKADDR);
char recvBuf[100];

recvfrom(sockSrv,recvBuf,100,0,(SOCKADDR*)&addrClient,&len);
printf("%s\n",recvBuf);
closesocket(sockSrv);
WSACleanup();
return 0;
}


1>test_udpclient.obj : error LNK2019: 无法解析的外部符号 __imp__closesocket@4,该符号在函数 _wmain 中被引用
1>test_udpclient.obj : error LNK2019: 无法解析的外部符号 __imp__sendto@24,该符号在函数 _wmain 中被引用
1>test_udpclient.obj : error LNK2019: 无法解析的外部符号 __imp__htons@4,该符号在函数 _wmain 中被引用
1>test_udpclient.obj : error LNK2019: 无法解析的外部符号 __imp__inet_addr@4,该符号在函数 _wmain 中被引用
1>test_udpclient.obj : error LNK2019: 无法解析的外部符号 __imp__socket@12,该符号在函数 _wmain 中被引用
1>test_udpclient.obj : error LNK2019: 无法解析的外部符号 __imp__WSACleanup@0,该符号在函数 _wmain 中被引用
1>test_udpclient.obj : error LNK2019: 无法解析的外部符号 __imp__WSAStartup@8,该符号在函数 _wmain 中被引用

出现以上的情况时,解决方法:在cpp文件Include后添加
#pragma comment(lib,"ws2_32.lib")
(责任编辑:admin)


文章转自:http://www.seacha.com/article.php/knowledge/windows/mfc/2012/0928/2043.html
【C++|C++ 网络套接字编程TCP和UDP实例】

    推荐阅读