C++ socket网络编程
程序员文章站
2022-04-08 22:50:14
...
1. 参考文献
2. TCP通信
@服务器端
// server.cpp : 定义控制台应用程序的入口点。
//
//TCP服务器端程序
#include "stdafx.h"
#include <iostream>
#include <WinSock2.h> //windows socket header file
#pragma comment(lib,"ws2_32.lib") //静态加入一个lib文件,也就是库文件ws2_32.lib,提供了对以下网络相关API的支持,否则需要动态载入ws2_32.dll
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
//初始化WSA
WORD sockVersion = MAKEWORD(2, 2); //MAKEWORD 宏返回一个word大小的内存 高位是2 低位也是2 所以版本是2.2
WSADATA wsaData; //数据结构,用来存储被WSAStartup函数调用后返回的Windows Sockets数据
//WSA:Windows Sockets Asynchronous,Windows异步套接字的启动命令.WSAStartup必须是应用程序或DLL调用的第一个Windows Sockets函数
if (WSAStartup(sockVersion, &wsaData) != 0)
{
return 0;
}
//创建套接字
SOCKET slisten = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); //sock_stream:字节流传输
if (slisten == INVALID_SOCKET) //invalid socket:无效的套接字
{
cout << "create socket error !" << endl;
return 0;
}
//绑定IP和端口
sockaddr_in sin; //IPv4 Socket address, internet style
sin.sin_family = AF_INET; //sin_family表示协议族,af_inet表示tcp/ip协议
sin.sin_port = htons(8888); //sin_port表示端口号
sin.sin_addr.S_un.S_addr = INADDR_ANY; //sin_addr表示联合体,可以用多种方式表示ip地址,一般我们使用其中的最后一种方式,
//即用无符号长整型数据来表示IP地址。此时,用的是s_nu数据成员,s_un是一个结构体,
//其中只有一个数据成员,即s_addr。
//INADDR_ANY就是指定地址为0.0.0.0的地址,这个地址事实上表示不确定地址,或“所有地址”、“任意地址”。
//绑定套接字到一个IP地址和一个端口上(bind()),slisten:套接字,sin:IPv4 Socket address and internet style
if (bind(slisten, (LPSOCKADDR)&sin, sizeof(sin)) == SOCKET_ERROR)
{
cout << "bind error !" << endl;
}
//开始监听
if (listen(slisten, 5) == SOCKET_ERROR)//5:后备日志当前被(默认地)限制为5
{
cout << "listen error !" << endl;
return 0;
}
//循环接收数据
SOCKET sClient;
sockaddr_in remoteAddr;
int nAddrlen = sizeof(remoteAddr);
char revData[255];
while (true)
{
cout << "阻塞。。。。等待连接。。。" << endl;
//请求到来后,接受连接请求,返回一个新的对应于此次连接的套接字(accept())
sClient = accept(slisten, (SOCKADDR *)&remoteAddr, &nAddrlen);
if (sClient == INVALID_SOCKET)//无效套接字
{
cout << "accept error !" << endl;
continue;
}
//将一个32位网络字节序的二进制IP地址转换成相应的点分十进制的IP地址
cout << "接受到一个连接:" << inet_ntoa(remoteAddr.sin_addr) << endl;
//接收数据
int ret = recv(sClient, revData, 255, 0);
if (ret > 0)
{
revData[ret] = 0x00;
//printf(revData);
cout << revData << endl;
//cout << endl;
}
//发送数据
const char * sendData = "你好,TCP客户端!\n";
send(sClient, sendData, strlen(sendData), 0);
closesocket(sClient);
}
closesocket(slisten);//关闭加载的套接字
WSACleanup();
return 0;
}
@客户端
// client.cpp : 定义控制台应用程序的入口点。
//
//TCP客户端程序
#include "stdafx.h"
#include<winsock2.h>
#include<iostream>
#include<string>
using namespace std;
#pragma comment(lib, "ws2_32.lib")
int _tmain(int argc, _TCHAR* argv[])
{
WORD sockVersion = MAKEWORD(2, 2);
WSADATA data;
if (WSAStartup(sockVersion, &data) != 0)
{
return 0;
}
//加载套接字库,创建套接字(WSAStartup()/socket())
while (true)
{
SOCKET sclient = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (sclient == INVALID_SOCKET)
{
cout << "invalid socket!" << endl;
return 0;
}
sockaddr_in serAddr;
serAddr.sin_family = AF_INET;
serAddr.sin_port = htons(8888);
serAddr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
if (connect(sclient, (sockaddr *)&serAddr, sizeof(serAddr)) == SOCKET_ERROR)
{
//连接失败
cout << "connect error !" << endl;
closesocket(sclient);
return 0;
}
string data;
cin >> data;
const char * sendData;
sendData = data.c_str(); //string转const char*
/*
send()用来将数据由指定的socket传给对方主机
int send(int s, const void * msg, int len, unsigned int flags)
s为已建立好连接的socket,msg指向数据内容,len则为数据长度,参数flags一般设0
成功则返回实际传送出去的字符数,失败返回-1,错误原因存于error
*/
send(sclient, sendData, strlen(sendData), 0);
char recData[255];
int ret = recv(sclient, recData, 255, 0);
if (ret>0)
{
recData[ret] = 0x00;
cout << recData << endl;
}
closesocket(sclient);
}
WSACleanup();
system("pause");
return 0;
}
3. UDP通信
@服务器端
// UDP_client.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <iostream>
#include <WinSock2.h>
#pragma comment(lib,"ws2_32.lib")
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
//启动WSA
WORD sockVersion = MAKEWORD(2, 2);
WSADATA wsaData;
if (WSAStartup(sockVersion, &wsaData) != 0)
{
return 0;
}
//创建套接字
SOCKET serSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (serSocket == INVALID_SOCKET)
{
cout << "Server socket has error!" << endl;
return 0;
}
//绑定IP和端口
sockaddr_in serAddr;
serAddr.sin_family = AF_INET; //协议族,af_inet表示tcp/udp协议
serAddr.sin_port = htons(8888); //端口号
serAddr.sin_addr.S_un.S_addr = INADDR_ANY;//INADDR_ANY指定地址为0.0.0.0,这个地址表示不确定地址,或者“所有地址”
if (bind(serSocket, (sockaddr*)&serAddr, sizeof(serAddr)) == SOCKET_ERROR)
{
cout << "Bind error!" << endl;
closesocket(serSocket);
return 0;
}
//循环接受数据
sockaddr_in remoteAddr;
int nAddrLen = sizeof(remoteAddr);
while (true)
{
char revData[255];
int ret = recvfrom(serSocket, revData, 255, 0, (sockaddr*)&remoteAddr, &nAddrLen);
if (ret > 0)
{
revData[ret] = 0x00;
cout << "接受到一个连接:" << inet_ntoa(remoteAddr.sin_addr) << "\r\n";
cout << revData << endl;
}
const char * sendData = "一个来自服务端的UDP数据包\n";
sendto(serSocket, sendData, strlen(sendData), 0, (sockaddr *)&remoteAddr, nAddrLen);
}
closesocket(serSocket);
WSACleanup();
system("pause");
return 0;
}
@客户端
// UDP_server.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <WinSock2.h>
#include <iostream>
#include <string>
#pragma comment(lib,"ws2_32.lib")
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
//加载套接字
WSADATA serWsaData;
WORD sockVersion = MAKEWORD(2, 2);
if (WSAStartup(sockVersion, &serWsaData) != 0)
{
cout << "Startup error!" << endl;
return 0;
}
SOCKET sclient = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
sockaddr_in sin;
sin.sin_family = AF_INET;
sin.sin_port = htons(8888);
sin.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
int len = sizeof(sin);
string data;
cin >> data;
const char * sendData;
sendData = data.c_str(); //string转const char*
//const char * sendData = "来自客户端的数据包.\n";
sendto(sclient, sendData, strlen(sendData), 0, (sockaddr*)&sin, len);
char recvData[255];
int ret = recvfrom(sclient, recvData, 255, 0, (sockaddr *)&sin, &len);
if (ret > 0)
{
recvData[ret] = 0x00;
printf(recvData);
}
closesocket(sclient);
WSACleanup();
system("pause");
return 0;
}
推荐阅读
-
实例分析之用ASP编程实现网络内容快速查找的代码
-
PHP SOCKET编程详解
-
socket java编程(java中socket的用法)
-
python网络编程学习笔记(10):webpy框架
-
最基础的Python的socket编程入门教程
-
linux下的C\C++多进程多线程编程实例详解
-
python网络编程学习笔记(六):Web客户端访问
-
python网络编程学习笔记(八):XML生成与解析(DOM、ElementTree)
-
python网络编程学习笔记(五):socket的一些补充
-
python网络编程学习笔记(七):HTML和XHTML解析(HTMLParser、BeautifulSoup)