目錄
一、介紹
二、收數據
三、發數據
?
一、介紹
tcp和udp的區別之一,即tcp是有連接的,udp是無連接的,udp收發數據的代碼可以獨立運行,tcp發數據前必須確保收數據的一方是打開的,否則無法建立連接。
二、收數據
tcpRecv.h
#pragma once
#include<iostream>
#include<winsock.h>
#pragma comment(lib,"ws2_32.lib")
using namespace std;class tcpRecv
{
public:tcpRecv();~tcpRecv();void initialization();void recvData();
public://定義發送緩沖區和接受緩沖區char send_buf[100];char recv_buf[100];//定義服務端套接字,接受請求套接字SOCKET s_server;SOCKET s_accept;//服務端地址客戶端地址SOCKADDR_IN server_addr;SOCKADDR_IN accept_addr;
};
?tcpRecv.cpp
#include "tcpRecv.h"tcpRecv::tcpRecv()
{initialization();//填充服務端信息server_addr.sin_family = AF_INET;server_addr.sin_addr.S_un.S_addr = htonl(INADDR_ANY);server_addr.sin_port = htons(14555);//創建套接字s_server = socket(AF_INET, SOCK_STREAM, 0);if (bind(s_server, (SOCKADDR *)&server_addr, sizeof(SOCKADDR)) == SOCKET_ERROR) {cout << "套接字綁定失敗!" << endl;WSACleanup();}else {cout << "套接字綁定成功!" << endl;}//設置套接字為監聽狀態if (listen(s_server, SOMAXCONN) < 0) {cout << "設置監聽狀態失敗!" << endl;WSACleanup();}else {cout << "設置監聽狀態成功!" << endl;}cout << "服務端正在監聽連接,請稍候...." << endl;//接受連接請求int len = sizeof(SOCKADDR);s_accept = accept(s_server, (SOCKADDR *)&accept_addr, &len);if (s_accept == SOCKET_ERROR) {cout << "連接失敗!" << endl;WSACleanup();}cout << "連接建立,準備接受數據" << endl;
}tcpRecv::~tcpRecv()
{//關閉套接字closesocket(s_server);closesocket(s_accept);//釋放DLL資源WSACleanup();
}void tcpRecv::initialization() {//初始化套接字庫WORD w_req = MAKEWORD(2, 2);//版本號WSADATA wsadata;int err;err = WSAStartup(w_req, &wsadata);if (err != 0) {cout << "初始化套接字庫失敗!" << endl;}else {cout << "初始化套接字庫成功!" << endl;}//檢測版本號if (LOBYTE(wsadata.wVersion) != 2 || HIBYTE(wsadata.wHighVersion) != 2) {cout << "套接字庫版本號不符!" << endl;WSACleanup();}else {cout << "套接字庫版本正確!" << endl;}//填充服務端地址信息}void tcpRecv::recvData() {//接收數據int recv_len = recv(s_accept, recv_buf, 100, 0);if (recv_len < 0) {cout << "接受失敗!" << endl;}else {cout << "接收信息為:" << recv_buf << endl;}
}
?main.cpp
#include "tcpRecv.h"int main() {tcpRecv tcp;while (1) {tcp.recvData();}return 0;
}
三、發數據
tcpSend.h
#pragma once
#include<iostream>
#include<string>
#include<winsock.h>
#pragma comment(lib,"ws2_32.lib")
using namespace std;class tcpSend
{
public:tcpSend();~tcpSend();void initialization();void sendData(std::string&data);
public://定義服務端套接字,接受請求套接字SOCKET s_server;//服務端地址客戶端地址SOCKADDR_IN server_addr;
};
?tcpSend.cpp
#include "tcpSend.h"tcpSend::tcpSend()
{initialization();//填充服務端信息server_addr.sin_family = AF_INET;server_addr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");server_addr.sin_port = htons(14555);//創建套接字s_server = socket(AF_INET, SOCK_STREAM, 0);if (connect(s_server, (SOCKADDR *)&server_addr, sizeof(SOCKADDR)) == SOCKET_ERROR) {cout << "服務器連接失敗!" << endl;WSACleanup();}else {cout << "服務器連接成功!" << endl;}
}tcpSend::~tcpSend()
{//關閉套接字closesocket(s_server);//釋放DLL資源WSACleanup();
}void tcpSend::initialization() {//初始化套接字庫WORD w_req = MAKEWORD(2, 2);//版本號WSADATA wsadata;int err;err = WSAStartup(w_req, &wsadata);if (err != 0) {cout << "初始化套接字庫失敗!" << endl;}else {cout << "初始化套接字庫成功!" << endl;}//檢測版本號if (LOBYTE(wsadata.wVersion) != 2 || HIBYTE(wsadata.wHighVersion) != 2) {cout << "套接字庫版本號不符!" << endl;WSACleanup();}else {cout << "套接字庫版本正確!" << endl;}//填充服務端地址信息}void tcpSend::sendData(std::string&data) {int send_len = send(s_server, data.c_str(), sizeof(data), 0);if (send_len < 0) {cout << "發送失敗!" << endl;}else {std::cout << "send data:" << data.c_str() << std::endl;}}
?main.cpp
#include "tcpSend.h"int main() {tcpSend tcp;for (int i = 0; i < 100; i++) {std::string s = "test " + std::to_string(i);tcp.sendData(s);Sleep(1000);}return 0;
}
?