基于TCP的Socket
在WIN32平台上的WINSOCK编程都要经过下列步骤:
定义变量->获得WINDOCK版本->加载WINSOCK库->初始化->创建套接字->设置套接字选项->关闭套接字->卸载WINSOCK库->释放资源
服务器端
具体函数
1、创建一个socket,用函数socket()
int socket(int domain, int type, int protocol);
其中 “int domain”参数表示套接字要使用的协议簇,协议簇的在“linux/socket.h”里有详细定义,常用的协议簇:
AF_UNIX(本机通信)
AF_INET(TCP/IP – IPv4)
AF_INET6(TCP/IP – IPv6)
其中 “type”参数指的是套接字类型,常用的类型有:
SOCK_STREAM(TCP流)
SOCK_DGRAM(UDP数据报)
SOCK_RAW(原始套接字)
最后一个 “protocol”一般设置为“0”,也就是当确定套接字使用的协议簇和类型时,这个参数的值就为0,但是有时候创建原始套接字时,并不知道要使用的协议簇和类型,也就是domain参数未知情况下,这时protocol这个参数就起作用了,它可以确定协议的种类。
socket是一个函数,那么它也有返回值,当套接字创建成功时,返回套接字,失败返回“-1”,错误代码则写入“errno”中。
2、绑定IP和端口等信息到socket上,bind()
3、设置允许的最大连接数,listen()
4、接收客户端上的请求,accept()
5、收发数据,send() recv()或read() write()
6、关闭网络连接,close()
代码
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#include<WinSock2.h>
#include<stdio.h>
#include<stdlib.h>
#pragma comment(lib,"ws2_32.lib")
const int BUF_SIZE = 1024;
int main()
{
//初始化WSA
WSADATA wsadata;// 建立一个WSADATA结构,通常用wsaData
WSAStartup(MAKEWORD(2, 2), &wsadata);/*调用WSAStartup函数,这个函数是连接应用程序与winsock.dll的第一个调用.其中,第一个参数是WINSOCK 版本号,第二个参数是指向WSADATA的指针.该函数返回一个INT型值,通过检查这个值来确定初始化是否成功.调用格式如下:WSAStartup(MAKEWORD(2,2),&wsaData),其中MAKEWORD(2,2)表示使用WINSOCK2版本.wsaData用来存储系统传回的关于WINSOCK的资料.*/
SOCKET serSock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);/*// 第一个参数是地址描述符,常用AF_INET(表示IPV4),第二个参数必须SOCK_STREAM,表示TCP连接,第三个参数是套接口所用的协议,不想调用就用0*/
sockaddr_in sockAddr;//套接字地址是一个数据结构,包含地址类型、端口号、IP地址、填充字节这4种数据
memset(&sockAddr, 0, sizeof(sockAddr)); //用0填充每一个字节
sockAddr.sin_family = AF_INET; //使用IPv4地址,也可以用PF_INET,在windows中AF_INET与PF_INET完全一样. 而在Unix/Linux系统中,在不同的版本中这两者有微小差别.对于BSD,是AF,对于POSIX是PF.
sockAddr.sin_addr.s_addr = inet_addr("127.0.0.1"); //具体的ip地址
sockAddr.sin_port = htons(5099); //具体的端口号
//绑定套接字
bind(serSock, (SOCKADDR*)&sockAddr, sizeof(sockAddr));
listen(serSock, 20);
//接受客户端请求
SOCKADDR clientAddr;
int clientAddr_size = sizeof(clientAddr);
SOCKET clientSock = accept(serSock, (SOCKADDR*)&clientAddr, &clientAddr_size);
//向客户端发送消息
char str[BUF_SIZE] = "hello world!!";
send(clientSock, str, strlen(str) + sizeof(char), NULL);
//关闭套接字
closesocket(clientSock);
closesocket(serSock);
WSACleanup();
system("pause");
return 0;
}
客户端
相关函数
1、创建一个socket,用函数socket()
2、设置要连接的对方的IP地址和端口等属性
3、连接服务器,connect()
4、收发数据,send() recv()或read() write()
5、关闭网络连接,close()
代码
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#include<iostream>
#include<string>
#include<stdio.h>
#include<winsock2.h>
using namespace std;
#pragma comment(lib,"ws2_32.lib")
const int BUF_SIZE = 100;
int main()
{
WSADATA wsadata;
WSAStartup(MAKEWORD(2, 2), &wsadata);
//需要连接服务端的信息
sockaddr_in sockAddr;
memset(&sockAddr, 0, sizeof(sockAddr));
sockAddr.sin_family = AF_INET;
sockAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
sockAddr.sin_port = htons(5099);
//创建套接字并连接
SOCKET sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
connect(sock, (SOCKADDR*)& sockAddr, sizeof(sockAddr));
char infoBuff[MAXBYTE] = { 0 };
recv(sock, infoBuff, MAXBYTE, NULL);
cout << "从服务器接受到得信息为:" << infoBuff << endl;
closesocket(sock);
WSACleanup();
system("pause");
return 0;
}