TCP socket编程
本文以windows socket 进行讲解, 开发环境VS2010,测试平台 windows 7
众所周知TCP(Transmission Control Protocol )是一种面向连接的、可靠的、基于字节流的通信协议。而开发TCP socket应用程序是一件比较简单的事情。下面就用一个比较简单的demo 讲解开发的过程。
该程序分为客户端和服务器端,客户端主要是向服务器端发送数据,服务器端主要是对于接收的数据进行显示。
TCP服务器端和客户端的主要流程:
服务器端:1 创建套接字 2 绑定 3 监听 4 接受连接 5 收发数据 6 关闭
客户端: 1 创建套接字 2 连接 3 收发数据 4 关闭
实现中用到的主要函数及
服务器: 1 WSAStartup() 2 socket() 3 bind() 4 listen() 5 accept() 6 recv() 7 closesocket() 8 WSACleanup()
客户端: 1 WSAStartup() 2 socket() 3 connect() 4 send() 5 closesocket() 6 WSACleanup()
下面是server 和 client 的实现代码,运行的时候首先启动server,然后再启动client, 则在server部分打印出“hello world” 。
Server.cpp 源码
#include "stdafx.h" #define BUF_SZIE 64 #include "winsock2.h" #pragma comment(lib, "ws2_32.lib") int main(int argc, char* argv[]) { WSADATA wsd; /*初始化套结字动态库*/ if (WSAStartup(MAKEWORD(2,2), &wsd) != 0) { printf("WSAStartup failed!\n"); return 1; } /*创建套接字*/ SOCKET sServer = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if(INVALID_SOCKET == sServer) { printf("socket failed!\n"); WSACleanup(); return -1; } /*服务器套接字地址*/ SOCKADDR_IN addrServ; addrServ.sin_family = AF_INET; addrServ.sin_port = htons(4999); addrServ.sin_addr.s_addr = INADDR_ANY; /*绑定套接字*/ int retVal = bind(sServer, (LPSOCKADDR)&addrServ, sizeof(SOCKADDR_IN)); if (SOCKET_ERROR == retVal) { closesocket(sServer); WSACleanup(); return -1; } /*开始监听*/ retVal = listen(sServer, 1); if(SOCKET_ERROR == retVal) { closesocket(sServer); WSACleanup(); return -1; } /*接受客户端请求*/ sockaddr_in addrClient; int addrClientlen = sizeof(addrClient); SOCKET sClient = accept(sServer,(sockaddr FAR*)&addrClient, &addrClientlen); if(INVALID_SOCKET == sClient) { closesocket(sServer); WSACleanup(); return -1; } /*接收客户端数据*/ char buf[BUF_SZIE]; ZeroMemory(buf, BUF_SZIE); retVal = recv(sClient, buf, BUF_SZIE, 0); if (SOCKET_ERROR == retVal) { closesocket(sServer); closesocket(sClient); WSACleanup(); return -1; } printf("%s\n", buf); /*退出*/ closesocket(sServer); closesocket(sClient); WSACleanup(); getchar(); return 0; }
Client.cpp 源码
#include "stdafx.h" #define BUF_SZIE 64 #include "winsock2.h" #pragma comment(lib, "ws2_32.lib") int main(int argc, char* argv[]) { WSADATA wsd; if (WSAStartup(MAKEWORD(2,2), &wsd) != 0) { printf("WSAStartup failed!\n"); return -1; } /*创建套接字*/ SOCKET sHost = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if(INVALID_SOCKET == sHost) { WSACleanup(); return -1; } /*设置服务器地址*/ SOCKADDR_IN servAddr; servAddr.sin_family =AF_INET; servAddr.sin_addr.s_addr = inet_addr("127.0.0.1"); servAddr.sin_port = htons((short)4999); int nServAddlen = sizeof(servAddr); /*连接服务器*/ int retVal = connect(sHost, (LPSOCKADDR)&servAddr, sizeof(servAddr)); if(SOCKET_ERROR == retVal) { closesocket(sHost); WSACleanup(); return -1; } /*向服务器发送数据*/ char buf[BUF_SZIE]; ZeroMemory(buf, BUF_SZIE); strcpy(buf, "Hello world"); retVal = send(sHost, buf, strlen(buf), 0); if (SOCKET_ERROR == retVal) { closesocket(sHost); WSACleanup(); return -1; } /**退出*/ closesocket(sHost); WSACleanup(); getchar(); return 0; }