专栏首页xingoo, 一个梦想做发明家的程序员TCPServer TCPClient三次握手模拟编程

TCPServer TCPClient三次握手模拟编程

套接字创建和关闭:

SOCKET socket(int af,int type,int protocal);

套接字类型:

SOCK_STREAM 流套接字,TCP提供有连接的可靠传输

SOCK_DGRAM 数据包套接字,UDP提供无连接的不可靠传输

SOCK_RAW 原始套接字

绑定套接字到指定的IP地址和端口号

int bind(
SOCKET s,//套接字句柄
const struct sockaddr * name,//关联的本地地址
int namelen//地址的长度
);

监听

int listen(
SOCKET s,//套接字
int backlog//最大连接数
)

连接

int accept(
SOCKET s,
struct sockaddr* addr,//取得对方的地址信息
int* addrlen//指向地址长度
);

int connect(
  SOCKET s,
  const struct sockaddr FAR* name,//连接的地址信息
  int namelen  //结构长度
);

收发数据

int send(
SOCKET s,
const char FAR* buf,//要发送数据的缓冲区地址
int len,//缓冲区长度
int flags//指定调用方式,通常为0
);
int recv(
SOCKET s,
char FAR* buf,
int len,
int
);

TCPSERVER端代码:

 1 // TCP.cpp : 定义控制台应用程序的入口点。
 2 //
 3 
 4 #include "stdafx.h"
 5 #include <winsock2.h>
 6 #include <stdio.h>
 7 
 8 #pragma comment(lib,"WS2_32")
 9 class CInitSock
10 {
11 public:
12     CInitSock(BYTE minorVer=2,BYTE majorVer=2)
13     {
14         WSADATA wsaData;
15         WORD sockVersion = MAKEWORD(minorVer,majorVer);
16         if(::WSAStartup(sockVersion,&wsaData)!=0)
17         {
18             exit(0);
19         }
20     }
21     ~CInitSock()
22     {
23         ::WSACleanup();
24     }
25 };
26 CInitSock initSock;
27 int _tmain(int argc, _TCHAR* argv[])
28 {
29     SOCKET sListen = ::socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
30     if(sListen == INVALID_SOCKET)
31     {
32         printf("Failed socket()\n");
33         return 0;
34     }
35     //填充sockaddr_in结构
36     sockaddr_in sin;
37     sin.sin_family = AF_INET;
38     sin.sin_port = htons(4567);
39     sin.sin_addr.S_un.S_addr = INADDR_ANY;
40     //绑定这个套接字的一个本地地址
41     if(::bind(sListen,(LPSOCKADDR)&sin,sizeof(sin)) == SOCKET_ERROR)
42     {
43         printf("Failed bind()\n");
44         return 0;
45     }
46     //进入监听模式
47     if(::listen(sListen,2) == SOCKET_ERROR)
48     {
49         printf("Failed listen()\n");
50         return 0;
51     }
52     //循环接受客户的连接请求
53     sockaddr_in remoteAddr;
54     int nAddrLen = sizeof(remoteAddr);
55     SOCKET sClient;
56     char szText[] = "TCP Server Demo!\r\n";
57     while(TRUE)
58     {
59         //接受新连接
60         sClient=::accept(sListen,(SOCKADDR*)&remoteAddr,&nAddrLen);
61         if(sClient == INVALID_SOCKET)
62         {
63             printf("Failed accept()");
64             continue;
65         }
66         printf("接受到一个连接:%s\r\n",inet_ntoa(remoteAddr.sin_addr));
67         //向客户端发送数据
68         ::send(sClient,szText,strlen(szText),0);
69         //关闭同客户端的连接
70         ::closesocket(sClient);
71     }
72     ::closesocket(sListen);
73     return 0;
74 }

TCPClient 端代码:

 1 // TCPClient.cpp : 定义控制台应用程序的入口点。
 2 //
 3 
 4 #include "stdafx.h"
 5 #include <winsock2.h>
 6 #include <stdio.h>
 7 #pragma comment(lib,"WS2_32")
 8 class CInitSock
 9 {
10 public:
11     CInitSock(BYTE minorVer=2,BYTE majorVer=2)
12     {
13         WSADATA wsaData;
14         WORD sockVersion = MAKEWORD(minorVer,majorVer);
15         if(::WSAStartup(sockVersion,&wsaData)!=0)
16         {
17             exit(0);
18         }
19     }
20     ~CInitSock()
21     {
22         ::WSACleanup();
23     }
24 };
25 CInitSock initSock;
26 
27 int _tmain(int argc, _TCHAR* argv[])
28 {
29     SOCKET s= ::socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
30     if(s==INVALID_SOCKET)
31     {
32         printf("Failed socket()\n");
33         return 0;
34     }
35     sockaddr_in servAddr;
36     servAddr.sin_family=AF_INET;
37     servAddr.sin_port=htons(4567);
38     servAddr.sin_addr.S_un.S_addr=inet_addr("49.140.16.244");
39     if(::connect(s,(sockaddr*)&servAddr,sizeof(servAddr))==-1)
40     {
41         printf("Failed connect()\n");
42         return 0;
43     }
44     //接受数据
45     char buff[256];
46     int nRecv=::recv(s,buff,256,0);
47     if(nRecv>0)
48     {
49         buff[nRecv] = '\0';
50         printf("接受到数据:%s",buff);
51     }
52     ::closesocket(s);
53     return 0;
54 }

结果:

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 剑指OFFER之重建二叉树(九度OJ1385)

    题目描述: 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7...

    用户1154259
  • 图m着色问题

    1 问题描述:   给定无向图,m种不同的颜色。使每一种着色法使G中每条边的2个顶点不同颜色,若一个图最少需要m种颜色才能使图中每条边连接的2个顶点着不同颜色,...

    用户1154259
  • cuda测试二维block的使用

    #include "cuda_runtime.h" #include <stdio.h> #include <stdlib.h> #include <math....

    用户1154259
  • Java 8 中的拉姆达表达式是什么?

    拉姆达表达式就是一个匿名函数。在 C#中,拉姆达表达式是一个委托类型,因此拉姆达表达式可以赋值给一个委托变量。 Java 中,没有委托,Java 的设计者只能...

    水货程序员
  • hdu1014

    @坤的
  • hdoj 4554 叛逆的小明

    xindoo
  • 算法和数据结构: 十二 无向图相关算法基础

    从这篇文章开始介绍图相关的算法,这也是Algorithms在线课程第二部分的第一次课程笔记。

    yaphetsfang
  • 编程填空:第i位替换 编程填空:第i位取反 编程填空:左边i位取反

    写出函数中缺失的部分,使得函数返回值为一个整数,该整数的第i位和m的第i位相同,其他位和n相同。

    Dar_Alpha
  • 基础算法|4 简单选择排序

    我们之前已经了解了三种基础算法,分别为二分查找算法,冒泡排序算法,以及直接插入排序算法。俗话说得好,温故而知新,所以现在就让我们简单回顾一下之前的三种算法吧。...

    ACM算法日常
  • c++之内存模型

    堆区:由程序员分配释放,若程序员不释放,则程序结束时由系统释放。在c++中主要利用new在堆区开辟内存。

    绝命生

扫码关注云+社区

领取腾讯云代金券