socket实现TCP通信
来源:互联网 发布:车载网络硬盘录像机 编辑:程序博客网 时间:2024/04/28 19:04
TCP是一种可靠的,面向连接的协议。
在socket中,建立TCP连接的过程大致如下:
服务器端:
1.初始化套接字
2.创建服务器socket
3.将本机地址与服务器socket绑定在一起
4.服务器开始监听
5.服务器确认请求(确认之前时一种阻塞的状态),accept()函数生成一个新的socket。
6.用新生成的socket接收数据
客户端:
1.初始化套接字
2.生成与服务器连接的socket
3.将socket与服务器进行连接
4.向服务器发送数据
以上过程需要用到以下一些函数:
1.SOCKET socket(int 地址族,int 套接字类型,int 协议类型),返回生成的SOCKET
2.int bind(SOCKET 要绑定的套接字,const sockaddr* 要绑定的地址的结构体的指针,int 第二个参数的长度)
在服务器端,用作监听客户端连接请求的套接字一定要经过绑定。
在客户端使用的套接字一般不必绑定,除非要指定它使用特定的网络地址。
3. int listen(SOCKET 要监听的套接字,int 最大允许等待连接长度)
适用于支持连接的套接字。仅用于服务器。
4.SOCKET accept(SOCKET 监听套接字,sockaddr* 客户端的地址结构,int* 客户端地址长度)
accept函数将从listen的等待队列中抽取出一个项,建立TCP连接,返回一个已经经过了连接的新的套接字。
若队列中没有连接请求,当:
阻塞方式时,该函数阻塞调用它的进程。
非阻塞方式时,该函数返回一个错误代码。
5.int connect(SOCKET s,const sockaddr* 服务器端地址结构,int 服务器端地址长度)
用于客户端请求向服务器端建立连接。
6.int recv(SOCKET 已建立连接的套接字,char* 接收字符串的缓冲区,int 缓冲区长度,int 选项一般为0)
返回实际接收的字节数
7.int send(SOCKET 已建立连接的套接字,char* 发送字符串的缓冲区,int 缓冲区长度,int 选项一般为0)
返回实际发送的字节数
源代码如下:
服务器端:
#include "stdafx.h"#include <iostream>#include <winsock2.h>#pragma comment(lib,"WS2_32.lib")#include <string.h>#define bufsize 64int main(){WSADATA wsd;SOCKET sServer, sClient;int retval;char recvbuf[bufsize];if (WSAStartup(MAKEWORD(2, 2), &wsd) != 0){printf("startup failed\n");WSACleanup();return -1;}sServer = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);if (sServer == INVALID_SOCKET){printf("socket failed\n");WSACleanup();return -1;}sockaddr_in addrServ;addrServ.sin_family = AF_INET;addrServ.sin_port = htons(9000);addrServ.sin_addr.S_un.S_addr = htonl(INADDR_ANY);//INADDR_ANY是IP地址0.0.0.0,表示来自任意IP地址的请求均接收retval = bind(sServer, (sockaddr*)&addrServ, sizeof(sockaddr_in));if (retval == SOCKET_ERROR){printf("bind failed\n");WSACleanup();return -1;}retval = listen(sServer, 1);if (retval == SOCKET_ERROR){printf("listen failed\n");closesocket(sServer);WSACleanup();return -1;}printf("TCP server start...\n");//至此,服务器启动完成sockaddr_in ClientAddr;int addrlen;addrlen = sizeof(ClientAddr);sClient = accept(sServer, (sockaddr*)&ClientAddr, &addrlen);//阻塞状态if (sClient == INVALID_SOCKET){printf("accept failed\n");closesocket(sServer);WSACleanup();return -1;}printf("client has log in\n");//打开客户端时,显示客户已登录while (true){memset(recvbuf, 0, sizeof(recvbuf));retval = recv(sClient, recvbuf, BUFSIZ, 0);if (retval == SOCKET_ERROR){printf("recv failed\n");closesocket(sClient);closesocket(sServer);WSACleanup();break;}printf("ip: %s\nport: %d\ncontent: %s\n", inet_ntoa(ClientAddr.sin_addr), ClientAddr.sin_port, recvbuf);}return 0;}
客户端:
#include "stdafx.h"#include <winsock2.h>#include <string>#include <string.h>#include <iostream>#include <stdio.h>#pragma comment(lib,"WS2_32.lib")#define bufsize 64int main(){WSADATA wsd;SOCKET sHost;sockaddr_in servaddr;char buf[bufsize];int retval;if (WSAStartup(MAKEWORD(2, 2), &wsd) != 0){printf("stratup failed\n");return -1;}sHost = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);if (sHost == INVALID_SOCKET){printf("socket failed\n");WSACleanup();return -1;}servaddr.sin_family = AF_INET;servaddr.sin_addr.S_un.S_addr = inet_addr("10.21.38.14");//服务器IP地址;servaddr.sin_port = htons(9000);int addrlen;addrlen = sizeof(servaddr);retval = connect(sHost, (sockaddr*)&servaddr, addrlen);if (retval == SOCKET_ERROR){printf("connect error\n");closesocket(sHost);WSACleanup();return -1;}while (1){printf("input the message:\n");std::string str;std::getline(std::cin, str);memset(buf, 0, sizeof(buf));strcpy(buf, str.c_str());retval = send(sHost, buf, strlen(buf), 0);if (retval == SOCKET_ERROR){printf("send failed\n");closesocket(sHost);WSACleanup();return -1;}} return 0;}
例如:
- socket实现TCP通信
- Java socket 实现tcp通信
- Java socket 实现tcp通信
- Python实现socket通信 (tcp)
- 网络通信 Socket 实现TCP
- C语言socket编程----实现TCP通信
- 用Socket实现TCP,UDP通信
- Socket使用TCP/IP如何实现通信
- Python实现TCP(socket)通信
- c语言实现TCP的socket通信
- java通过Socket实现TCP网络通信
- Socket 之 TCP 协议通信-c#实现
- Java Socket通信及TCP/UDP实现
- Socket TCP通信简单实现与文件传输
- tcp ip 通信socket
- socket网络通信(tcp)
- socket TCP通信实例
- socket网络通信(tcp)
- css----标记选择器,写入方法
- C++11学习
- Android相册解决加载大量图片卡顿问题
- Gstreamer的简单理解(转载)
- Category详解
- socket实现TCP通信
- 1.10:对象创建和生命期
- LeetCode-167. Two Sum II
- 读书笔记 effective c++ Item 15 在资源管理类中提供对原生(raw)资源的访问
- windows10 双屏幕扩展后,窗口拖动方向的问题。
- iOS UIslider 设定滑块的大小
- win10 uwp 简单MasterDetail
- bzoj 1370 团伙 并查集
- Redis之——搭建高可用及负载均衡的Redis