基于C/S的TCP/IP协议的socket编程
TCP/IP协议簇的特点:面向连接的,可靠的,基于字节流的传输协议 UDP/IP协议簇的特点:面向不连接的,不可靠的基于数据报的传输层协议
C/S模型:客户端/服务端模型。根据概念层面的,实现层面可以是任何网络。
服务端:
1. 打开网络库
2.检验版本
3.创建socket
4.绑定地址与端口(bind)
5.开始监听
6.创建客户端socket(accept)
7.与客户机收发消息 (1)收(recv):得到客户端收到的参数 数据接收都是协议本身做的,
也就是socket的底层做的系统会有一段缓冲区,储存着接受的数据
recv的作用就是通过socket找到缓冲区,并将数据复制出来。
(2)发(send):向目标发送数据。send的作用就是通过socket找到缓冲区,并将数据粘贴出来。
客户端
1. 打开网络库
2.检验版本
3.创建socket
4.链接到服务器(connect)
7.与服务机收发消息 (1)收(recv):得到客户端收到的参数
(2)发(send):向目标发送数据
服务端
#include <stdio.h>
#include <stdlib.h>
#include<iostream>
#include <WinSock2.h>
using namespace std;
#pragma comment(lib,"Ws2_32.lib")
BOOL g_nFlag = TRUE;
int main(void)
{
WORD wdVersion = MAKEWORD(1, 1);
WSADATA wsaData;
if (0 != WSAStartup(wdVersion, &wsaData))
{
printf("WSAStartup fail!");
return -1;
}
if (1 != HIBYTE(wsaData.wVersion) || 1 != LOBYTE(wsaData.wVersion))
{
printf("Version fail!");
WSACleanup();
return -1;
}
SOCKET socketListen = socket(AF_INET, SOCK_STREAM, 0);
if (INVALID_SOCKET == socketListen)
{
printf("socket fail!");
WSACleanup();
return -1;
}
SOCKADDR_IN sockAddress;
sockAddress.sin_family = AF_INET;
sockAddress.sin_addr.s_addr = 16777343;
sockAddress.sin_port = 12345;
if (SOCKET_ERROR == bind(socketListen, (struct sockaddr*) & sockAddress, sizeof(sockAddress)))
{
printf("bind fail!");
closesocket(socketListen);
WSACleanup();
return -1;
}
if (SOCKET_ERROR == listen(socketListen, 2))
{
cout << "listen fail!" << endl;
closesocket(socketListen);
WSACleanup();
return -1;
}
SOCKADDR_IN sockClient;
int nLen = sizeof(sockClient);
SOCKET newSocket;
newSocket = accept(socketListen, NULL, NULL);
if (INVALID_SOCKET == newSocket)
{
printf("listen fail!");
closesocket(socketListen);
WSACleanup();
return -1;
}
while (g_nFlag)
{
char szRecvBuffer[1400] = { 0 };
char szSendBuffer[1024];
int nReturnValue = recv(newSocket, szRecvBuffer, sizeof(szRecvBuffer) - 1, 0);
int nRes = WSAGetLastError();
if (0 == nReturnValue)
{
continue;
}
else if (SOCKET_ERROR == nReturnValue)
{
printf("客户端中断连接");
continue;
}
else
{
cout << "Client Data :" << szRecvBuffer << endl;
}
}
closesocket(socketListen);
closesocket(newSocket);
WSACleanup();
return 0;
}
客户端
#include<winsock2.h>
#include<string>
#include<iostream>
using namespace std;
#pragma comment(lib,"ws2_32.lib")
int main()
{
WORD wdVersion = MAKEWORD(2, 2);
WSADATA wdSockMsg;
int nRes = WSAStartup(wdVersion, &wdSockMsg);
if (0 != nRes)
{
switch (nRes)
{
case WSASYSNOTREADY:
cout << "底层网络子系统尚未准备好进行网络通信。" << endl;
break;
}
}
SOCKET socketserver = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if(INVALID_SOCKET== socketserver)
{
int a = WSAGetLastError();
cout<< "创建socket失败" << endl;
WSACleanup();
return 0;
}
sockaddr_in serverMsg;
serverMsg.sin_family = AF_INET;
serverMsg.sin_port = 12345;
serverMsg.sin_addr.S_un.S_addr =16777343;
int bres = connect(socketserver, (sockaddr*)& serverMsg, sizeof(serverMsg));
if (SOCKET_ERROR == bres)
{
cout << "链接客户端失败" << endl;
int a = WSAGetLastError();
closesocket(socketserver);
WSACleanup();
return 0;
}
while (1)
{
char szSendData[1024];
cout << "Input Something:" << endl;
cin >> szSendData;
if (SOCKET_ERROR == send(socketserver, szSendData, sizeof(szSendData), 0))
{
cout << "send fail!" << endl;
closesocket(socketserver);
WSACleanup();
return 0;
}
}
closesocket(socketserver);
WSACleanup();
system("pause");
return 0;
}
|