文章目录

前言一、TCP通信1、客户端源码1.1、PreInclude.h1.2、Client.h1.3、Client.cpp

2、服务端源码2.1、Server.h2.2、Server.cpp

3、运行示意图

二、UDP通信1、客户端源码1.1、UDP_Client.h1.2、UDP_Client.cpp

2、服务端源码2.1、UDP_Server.h2.2、UDP_Server.cpp

3、运行示意图

前言

TCP(Transmission Control Protocol,传输控制协议)和UDP(User Data Protocol ,用户数据报协议)都属于TCP/IP协议簇。其中,TCP是面向连接的协议,在数据传输之前必须通过"三次握手"与对方建立可靠的连接,当数据传输完毕后通过"四次挥手"与服务端断开连接,这样可以保证数据传输的可靠性。也正是其的可靠性,TCP通信经常用于需要保证网络通信内容完整性的情况,比如网页HTTP、QQ文件传输等过程。而,UDP是一个面向无连接的协议,在数据传输之前,发送端和接收端不建立连接,发送端尽可能快的将数据扔到网络上,接收端从消息队列中读取消息段。如果接收方接收报文后校验失败,则直接将报文丢弃,不做任何处理。也正是因为这种特性,UDP通信一般用于要求网络通讯速度尽量的快(对网络通讯质量要求不高)的情况下,如QQ语音、QQ视频等。

一、TCP通信

1、客户端源码

1.1、PreInclude.h

#ifndef PREINCLUDE_H

#define PREINCLUDE_H

#define WIN32_LEAN_AND_MEAN

//#define _WINSOCK_DEPRECATED_NO_WARNINGS

#include

#include

#include

#include

#include

#pragma comment(lib, "ws2_32.lib")//windows�µ��ö�̬��

#pragma pack(1)

struct DataPackage {

int dealMode;

char str[32];

};

#define SERVER_IP "127.0.0.1"

#define SERVER_PORT 65151

#endif //PREINCLUDE_H

1.2、Client.h

#ifndef CLIENT_H

#define CLIENT_H

#include "../PreInclude.h"

void ClientAPI();

#endif //CLIENT_H

1.3、Client.cpp

#include "../Client/Client.h"

void ClientAPI()

{

//加载Windows环境

WORD ver = MAKEWORD(2, 2);

WSADATA dat;

WSAStartup(ver, &dat);

//创建socket

SOCKET Client_sock = socket(AF_INET, SOCK_STREAM, 0);

if (INVALID_SOCKET == Client_sock) {

printf("Build client's socket failed!!!\n");

}

else {

printf("Build client's socket successful...\n");

}

//

sockaddr_in Server_sin = {};

Server_sin.sin_family = AF_INET;

Server_sin.sin_port = htons(SERVER_PORT);

//Server_sin.sin_addr.S_un.S_addr = inet_addr("127.0.0.1"); //INADDR_ANY为默认IP

//将十进制SERVER_IP转化为二进制保存至Server_sin.sin_addr中

inet_pton(AF_INET, SERVER_IP, &Server_sin.sin_addr);

//调用connect函数连接服务端

int connectRet = connect(Client_sock, (sockaddr*)&Server_sin, sizeof(sockaddr_in));

if (INVALID_SOCKET == connectRet) {

printf("Connect failed!!!\n");

}

else {

printf("Connect successfully...\n");

}

//缓冲区

while (true) {

//输入发送信息

DataPackage dp;

scanf_s("%d",&dp.dealMode);

//输入-1,表示结束

if (dp.dealMode==-1) {

break;

}

else {

scanf_s("%s", dp.str,32);

dp.str[strlen(dp.str)] = '\0';

//调用send函数,将缓冲区内的数据发送至服务端

send(Client_sock, (const char*)&dp, sizeof(DataPackage), 0);

}

//初始化接收缓冲区,调用recv函数进行数据接收

char recvBuf[1024] = {};

int nlen = recv(Client_sock, recvBuf, 127, 0);

if (nlen > 0) {

printf("Recv message successfully...\n");

printf("Message:%s\n", recvBuf);

}

memset(recvBuf, 0, sizeof(recvBuf));

}

//关闭客户端连接

closesocket(Client_sock);

//

WSACleanup();

printf("Client closed...");

getchar();

}

2、服务端源码

2.1、Server.h

#ifndef SERVER_H

#define SERVER_H

#include "../PreInclude.h"

//服务端处理信息,将字符换变为大写

void StrToUpper(char* str,int len);

//服务端处理信息,将字符换变为小写

void StrToLower(char* str,int len);

void ServerAPI();

#endif //SERVER_H

2.2、Server.cpp

#include "../Server/Server.h"

//服务端处理信息,将字符换变为大写

void StrToUpper(char* str,int len)

{

for(int i=0;i

{

str[i]=toupper(str[i]);

}

}

//服务端处理信息,将字符换变为小写

void StrToLower(char* str,int len)

{

for(int i=0;i

{

str[i]=tolower(str[i]);

}

}

void ServerAPI()

{

//加载Windows环境

WORD ver = MAKEWORD(2, 2);

WSADATA dat;

WSAStartup(ver, &dat);

//创建socket

SOCKET Server_sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

sockaddr_in Server_sin = {};

Server_sin.sin_family = AF_INET;

Server_sin.sin_port = htons(SERVER_PORT);

//Server_sin.sin_addr.S_un.S_addr = inet_addr("127.0.0.1"); //INADDR_ANY为默认地址

//将十进制SERVER_IP转化为二进制保存至Server_sin.sin_addr中

inet_pton(AF_INET, SERVER_IP, &Server_sin.sin_addr);

//调用bind,将服务端本地地址到socket上

if (SOCKET_ERROR == bind(Server_sock, (sockaddr*)&Server_sin, sizeof(Server_sin)))

{

printf("Bind failed!!!\n");

}

else {

printf("Bind successful...\n");

}

//调用listen函数进行监听

if (SOCKET_ERROR == listen(Server_sock, 5))

{

printf("Listen failed!!!\n");

}

else {

printf("Listen successful...\n");

}

//调用accept接收客户端连接申请,并将客户端信息保存至Client_sin中

sockaddr_in Client_sin = {};

char IPdotdec[20];

int nAddrLen = sizeof(sockaddr_in);

SOCKET Client_sock = INVALID_SOCKET;

Client_sock = accept(Server_sock, (sockaddr*)&Client_sin, &nAddrLen);

if (Client_sock == INVALID_SOCKET)

{

printf("Accept Client_sin failed!!!\n");

}

else

{

printf("Accept clirntAddr successful... Sock = %d,IP = %s \n", (int)Client_sock, inet_ntop(AF_INET, &Client_sin.sin_addr, IPdotdec, 16));

}

char sendError[127]="The message is error!!!";

char _recvBuf[128] = {};

while (true)

{

//调用recv函数接收客户端发送的信息

int nLen = recv(Client_sock, _recvBuf, 128, 0);

if (nLen <= 0) {

printf("Recv client's message failed!!!\n");

break;

}

printf("Recv successful...");

//根据接收到的信息,进行处理,并调用send返回对应的处理信息

DataPackage* dp= (DataPackage*)_recvBuf;

if(dp->dealMode==1){

StrToUpper(dp->str,strlen(dp->str));

send(Client_sock, (const char*)dp->str, strlen(dp->str), 0);

}

else if(dp->dealMode==2){

StrToLower(dp->str,strlen(dp->str));

send(Client_sock, (const char*)dp->str, strlen(dp->str), 0);

}

else{

send(Client_sock, (const char*)sendError, strlen(sendError), 0);

}

}

//当客户端断开连接后,会关闭客户端

closesocket(Server_sock);

//

WSACleanup();

printf("Sever closed ...");

}

3、运行示意图

二、UDP通信

1、客户端源码

1.1、UDP_Client.h

#ifndef UDP_CLIENT_H

#define UDP_CLIENT_H

#include "../PreInclude.h"

void UDP_ClientAPI();

#endif //CLIENT_H

1.2、UDP_Client.cpp

#include "../UDP_Client/UDP_Client.h"

void UDP_ClientAPI()

{

const size_t BufSize=1024;

char sendBuf[BufSize];

char recvBuf[BufSize];

//加载Windows环境

WORD ver = MAKEWORD(2, 2);

WSADATA dat;

WSAStartup(ver, &dat);

//创建socket

SOCKET Client_sock = socket(AF_INET, SOCK_DGRAM, 0);

if (-1 == Client_sock) {

printf("Build UDP_client's socket failed!!!\n");

}

else {

printf("Build UDP_client's socket successful...\n");

}

//

sockaddr_in Server_sin = {};

Server_sin.sin_family = AF_INET;

Server_sin.sin_port = htons(SERVER_PORT);

//Server_sin.sin_addr.S_un.S_addr = inet_addr("127.0.0.1"); //INADDR_ANY为默认IP

//将十进制SERVER_IP转化为二进制保存至Server_sin.sin_addr中

inet_pton(AF_INET, SERVER_IP, &Server_sin.sin_addr);

sockaddr_in Server_sock;

socklen_t len=sizeof(Server_sock);

//缓冲区

while (true) {

//输入发送信息

printf("Please input:\n");

scanf_s("%s", sendBuf, BufSize);

sendBuf[strlen(sendBuf)] = '\0';

//调用sendto函数,将缓冲区内的数据发送至服务端

sendto(Client_sock, sendBuf, strlen(sendBuf), 0, (SOCKADDR*)&Server_sin, sizeof(SOCKADDR));

int nlen = recvfrom(Client_sock, recvBuf, sizeof(recvBuf), 0, (SOCKADDR*)&Server_sock, &len);

printf("%d", nlen);

if (nlen > 0)

{

recvBuf[nlen] = '\0'; //给字符数组加一个'\0',表示结束了。不然输出有乱码

if (strcmp(recvBuf, "bye") == 0)

{

printf("Server close!!!");//当服务器发来bye时,关闭socket

closesocket(Client_sock);

break;

}

else

{

printf("Recv message sucessful... Message:%s\n", recvBuf);

}

}

memset(sendBuf, 0, sizeof(sendBuf));

memset(recvBuf, 0, sizeof(recvBuf));

}

//关闭客户端连接

closesocket(Client_sock);

//

WSACleanup();

printf("Client closed...");

getchar();

}

2、服务端源码

2.1、UDP_Server.h

#ifndef UDP_SERVER_H

#define UDP_SERVER_H

#include "../PreInclude.h"

//服务端处理信息,将字符换变为大写

void StrToUpper(char* str,int len);

//服务端处理信息,将字符换变为小写

void StrToLower(char* str,int len);

void UDP_ServerAPI();

#endif //SERVER_H

2.2、UDP_Server.cpp

#include "../UDP_Server/UDP_Server.h"

//服务端处理信息,将字符换变为大写

void StrToUpper(char* str,int len)

{

for(int i=0;i

{

str[i]=toupper(str[i]);

}

}

//服务端处理信息,将字符换变为小写

void StrToLower(char* str,int len)

{

for(int i=0;i

{

str[i]=tolower(str[i]);

}

}

void UDP_ServerAPI()

{

//加载Windows环境

WORD ver = MAKEWORD(2, 2);

WSADATA dat;

WSAStartup(ver, &dat);

//创建socket

SOCKET Server_sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);

sockaddr_in Server_sin = {};

Server_sin.sin_family = AF_INET;

Server_sin.sin_port = htons(SERVER_PORT);

//Server_sin.sin_addr.S_un.S_addr = inet_addr("127.0.0.1"); //INADDR_ANY为默认地址

//将十进制SERVER_IP转化为二进制保存至Server_sin.sin_addr中

inet_pton(AF_INET, SERVER_IP, &Server_sin.sin_addr);

//调用bind,将服务端本地地址到socket上

if (SOCKET_ERROR == bind(Server_sock, (sockaddr*)&Server_sin, sizeof(Server_sin)))

{

printf("Bind failed!!!\n");

}

else {

printf("Bind successful...\n");

}

//调用accept接收客户端连接申请,并将客户端信息保存至Client_sin中

sockaddr_in Client_sin = {};

char IPdotdec[20];

int nAddrLen = sizeof(sockaddr_in);

char recvBuf[1024] = {};

while (true)

{

//调用recv函数接收客户端发送的信息

int nLen = recvfrom(Server_sock, recvBuf, 1024, 0,(SOCKADDR*) &Client_sin, &nAddrLen);

if (nLen <= 0) {

printf("Recv client's message failed!!!\n");

break;

}

printf("Recv successful...");

recvBuf[nLen]='\0';

if(strcmp(recvBuf,"bye")==0)

{

printf("Client close!!!");

closesocket(Server_sock);

return ;

}

else

{

printf("Recv message sucessful from %s ...\n Message:%s\n", inet_ntoa(Client_sin.sin_addr), recvBuf);

}

StrToLower(recvBuf,strlen(recvBuf));

sendto(Server_sock,recvBuf, strlen(recvBuf), 0, (SOCKADDR*)&Client_sin, sizeof(SOCKADDR));

memset(recvBuf, 0, sizeof(recvBuf));

}

//当客户端断开连接后,会关闭客户端

closesocket(Server_sock);

//

WSACleanup();

printf("Sever closed ...");

}

3、运行示意图

源码地址:https://gitee.com/wang_jun_quan_admin/crawler 如需要,请自取。

相关阅读

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: