Socket编程(TCP)

来源:互联网 发布:网络安全技术徐剑 编辑:程序博客网 时间:2024/06/03 21:29

服务端的建立:

1, 加载SOCKET版本

2, 创建socket

3, 创建SOCKADDR_IN结构变量, 设置IP, 端口, 与地址族

4, 绑定IP与端口

5, 打开监听

6, 接收客户端连接请求

7, 开启通信.


客户端的建立:

1, 加载SOCKET版本

2, 创建socket

3, 创建SOCKADDR_IN结构变量, 设置IP, 端口, 与地址族

4, 连接服务端

5, 开启通信


windows下服务端的例子:

#include "stdafx.h"#include <WinSock2.h>int _tmain(int argc, _TCHAR* argv[]){using std::cout;WORD wVersion;WSADATA wsaData;wVersion = MAKEWORD(2, 2); //设置版本//WSAStartup 加载SOCKET版本, 成功返回0, 否则返回-1if (WSAStartup(wVersion/*设定的版本号*/, &wsaData/*OUT参数, 获取加载的版本信息*/)){cout<<"加载SOCK出错";std::cin.get();return -1;}if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) !=2){//验证版本信息是不为2, 2cout<<"加载SOCK版本出错";std::cin.get();//WSACleanup释放资源, 终止对SOCKET动态库的使用WSACleanup();return -1;}int sockLength = sizeof(SOCKADDR);//socket创建SOCKET, 成功返回一个新的SOCKET数据类型的套接字描述符, 失败返回 INVALID_SOCKETSOCKET sockServer = socket(AF_INET/*地址族*/, SOCK_STREAM/*指定流式套接字*/, 0/*一般设置为0, 自动选择一个合适的协议*/);SOCKADDR_IN sAddress;//inet_addr(将字符串IP型式转换为指定的ulong类型地址描述)//inet_ntoa(将指定的ulong类型地址描述转换成字符串IP型式)sAddress.sin_addr.S_un.S_addr = inet_addr("192.168.1.100");sAddress.sin_family = AF_INET;//htons把一个u_short类型的值从主机字节顺序转换为TCP/IP网络字节顺序//htonl把一个u_long类型的值从主机字节顺序转换为TCP/IP网络字节顺序sAddress.sin_port = htons(7777);//bind, 将该套接字绑定到指地的IP和端口上, 成功返回0, 否则返回 SOCKET_ERRORbind(sockServer, //创建的SOCKET(SOCKADDR*)&sAddress, //地址信息sockLength/*SOCKADDR的字节长度sizeof(SOCKADDR)*/);//listen, 开启监听, 成功返回0, 否则返回SOCKET_ERRORlisten(sockServer,//创建的SOCKET10/*打开服务会监听的客户数量*/);SOCKADDR_IN clientAddress;while(TRUE){//accept接收客户端发送的连接请求, 成功, 返回该客户端的SOCKET, 否则返回-1SOCKET client = accept(sockServer, //服务端SOCKET(SOCKADDR*)&clientAddress, //用来接收客户端地址&sockLength/*sizeof(SOCKADDR)*/);cout<<"链接OK";char sendBuffer[512];sprintf(sendBuffer, "%s 以登录成功", inet_ntoa(clientAddress.sin_addr)/*将ulong型式地址转换成字符串型式的IP地址*/);//send发送消息send(client, sendBuffer, strlen(sendBuffer) + 1/*这里注要多加1用来存放\0*/, 0);char recvBuffer[512] = {0};//recv接收消息, 失败返回0或者-1recv(client, recvBuffer, 512, 0);cout<<recvBuffer;closesocket(client);}cout<<"成功";std::cin.get();WSACleanup();return 0;}

windows下客户端的例子:

#include "stdafx.h"int _tmain(int argc, _TCHAR* argv[]){WORD wVersion;WSADATA wsaData;wVersion = MAKEWORD(2, 2); if (WSAStartup(wVersion, &wsaData)){std::cout<<"加载SOCK出错";std::cin.get();return -1;}if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2){std::cout<<"加载SOCK版本出错";std::cin.get();WSACleanup();return -1;}SOCKET client = socket(AF_INET, SOCK_STREAM, 0);SOCKADDR_IN hostAddress;hostAddress.sin_addr.S_un.S_addr = inet_addr("192.168.1.100");hostAddress.sin_family = AF_INET;hostAddress.sin_port = htons(7777);//connect连接指定的地址与端口int i = connect(client, (SOCKADDR*)&hostAddress, sizeof(SOCKADDR));if (i == 0){std::cout<<"连接成功\n";}char recvBuffer[512];recv(client, recvBuffer, 512, 0);std::cout<<recvBuffer;char sendBuffer[511];sprintf(sendBuffer, "客户端 登录成功");send(client, sendBuffer, strlen(sendBuffer) + 1/*这个很关键*/, 0);closesocket(client);WSACleanup();std::cin.get();return 0;}


这里仅是未了说明套接字的使用, 在实际应用当中, 都必需结合多线程处理套接字, 最好还要封装之后再使用


windows下获取本机IP:

char * IegadSock::GetHostIp(){//获取本机IPWSADATA wData;unsigned int version = MAKEWORD(2, 2);if (WSAStartup(version, &wData)){return 0;}if (LOBYTE(wData.wVersion) != 2 || HIBYTE(wData.wVersion) != 2){return 0;}char host_name[255]; //计算机名if (gethostname(host_name/*输出参数*/, sizeof(host_name)) == -1) //该函数获取计算机名{//该函数, 成功返回0return 0;}//gethostbyname()返回对应于给定主机名的包含主机名字和地址信息的hostent结构指针,失败返回NULLHOSTENT * phe = gethostbyname(host_name/*计算机名*/);if (!phe){return 0;}in_addr addr;//获取HOSTENT中的地址列表中第一个地址,并转换成字符串memcpy(&addr, phe->h_addr_list[0], sizeof(in_addr));char * IpString = inet_ntoa(addr);WSACleanup();return IpString;}


这里是Linux下的服务端:

#include <stdlib.h>#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#include <string.h>#include <iostream>int main(){   //unlink("server_socket");   int host = socket(AF_INET, SOCK_STREAM, 0);   if(host == -1)   {     std::cout<<"init error\n";     return -1;   }   std::cout<<"init done\n";   sockaddr_in s_add;   s_add.sin_family = AF_INET;   s_add.sin_addr.s_addr= inet_addr("192.168.1.104");   s_add.sin_port=htons(7777);   int err = bind(host, (sockaddr*)&s_add, sizeof(sockaddr));   if (err == -1)   {     std::cout<<"bind error\n";   }   std::cout<<"bind done\n";   err = listen(host, 10);   if (err == -1)   {     std::cout<<"listen error\n";   }   std::cout<<"listen...\n";   sockaddr_in c_add;   int len = sizeof(c_add);   int clnt = accept(host, (sockaddr*)&c_add, (socklen_t*)&len/*这里和windows下有区别*/);   if(clnt == -1)   {      std::cout<<"accpet error\n";   }   std::string sendMsg = "Hello guy\n";   err = write(clnt, sendMsg.c_str(), sendMsg.size() + 1);   if(err == -1)   {     std::cout<<"write error\n";   }   char msg[1024] = {0};   read(clnt, msg, 1024);   std::cout<<msg<<std::endl;   close(clnt);   close(host);   return 0;}

在linux下,是不需要加载版本的.也就是(WSAStartup()的调用)


0 0
原创粉丝点击