socket通信_TCP

TCP面向字节流传输数据,提供可靠的数据传输服务。通过TCP传送的数据无差错、不丢失、不重
复,而且按序到达。由于TCP是基于连接的,所以每一条TCP连接只能是点到点的交互通信。

服务器端初始化Winsock环境后,便调用Socket函数创建流式套接字;然后对sockaddr_in结构体进行设
置,设置服务器绑定的IP地址和端口等信息并调用 bind函数来绑定;绑定成功后,就可以调用listen函数设
置连接数量,并进行监听。直到有来自客户端的连接请求,服务器便调用accept函数接受连接请求,建立
连接。这时,可以使用recv函数和send函数与客户端进行数据收发。通信结束后,关闭套接字,释放资
源。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
#include<stdio.h>
#include <Winsock2.h>
#pragma comment(lib, "Ws2_32.lib")
#include<windows.h>

BOOL SocketBindAndListen(char *lpszIp, int iPort);
void SendMsg(char *pszSend);
void AcceptRecvMsg();

// 服务端套接字
SOCKET g_ServerSocket;
// 客户端套接字
SOCKET g_ClientSocket;

int main()
{
if (FALSE == SocketBindAndListen("127.0.0.1", 8888))
{
printf("SocketBindAndListen Error.\n");
}
printf("SocketBindAndListen OK.\n");

// 发送信息
char szSendBuf[MAX_PATH] = { 0 };
while (TRUE)
{
gets_s(szSendBuf);
// 发送数据
SendMsg(szSendBuf);
}

return 0;
}
// 绑定端口并监听
BOOL SocketBindAndListen(char *lpszIp, int iPort)
{
// 初始化 Winsock 库
WSADATA wsaData = { 0 };
WSAStartup(MAKEWORD(2, 2), &wsaData);

// 创建流式套接字
g_ServerSocket = socket(AF_INET, SOCK_STREAM, 0);
if (INVALID_SOCKET == g_ServerSocket)
{
return FALSE;
}
// 设置服务端地址和端口信息
sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_port = htons(iPort); addr.sin_addr.S_un.S_addr = inet_addr(lpszIp);
// 绑定IP和端口
if (0 != bind(g_ServerSocket, (sockaddr *)(&addr), sizeof(addr)))
{
return FALSE;
}
// 设置监听
if (0 != listen(g_ServerSocket, 1))
{
return FALSE;
}

// 创建接收数据多线程
CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)AcceptRecvMsg, NULL, NULL, NULL);

return TRUE;
}


// 发送数据
void SendMsg(char *pszSend)
{
// 发送数据
send(g_ClientSocket, pszSend, (1 + lstrlen(pszSend)), 0);
printf("[send]%s\n", pszSend);
}


// 接受连接请求 并 接收数据
void AcceptRecvMsg()
{
sockaddr_in addr = { 0 };
// 注意:该变量既是输入也是输出
int iLen = sizeof(addr);
// 接受来自客户端的连接请求
g_ClientSocket = accept(g_ServerSocket, (sockaddr *)(&addr), &iLen);
printf("accept a connection from client!\n");

char szBuf[MAX_PATH] = { 0 };
while (TRUE)
{
// 接收数据
int iRet = recv(g_ClientSocket, szBuf, MAX_PATH, 0);
if (0 >= iRet)
{
continue;
}
printf("[recv]%s\n", szBuf);
}
}

客户端初始化环境后,便调用Socket函数创建流式套接字;然后对sockaddr_in结构体进行设置,设置
服务器的IP地址和端口等信息并调用connect 函数向服务器发送连接请求,并等待服务器响应。服务器接
受连接请求后,就成功地与服务器建立连接,这时,可以使用recv函数和send函数与客户端进行数据收
发。通信结束后,关闭套接字,释放资源。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
#include <Winsock2.h>
#include<stdio.h>
#pragma comment(lib, "Ws2_32.lib")

SOCKET g_ClientSocket;
// 连接到服务器
BOOL Connection(char *lpszServerIp, int iServerPort);
// 发送数据
void SendMsg(char *pszSend);
// 创建接收数据多线程
void RecvMsg();

int main()
{
// 连接到服务器
if (FALSE == Connection("127.0.0.1", 8888))
{
printf("Connection Error.\n");
getchar();
exit(0);
}
printf("Connection OK.\n");

// 发送信息
char szSendBuf[MAX_PATH] = { 0 };
while (TRUE)
{
gets(szSendBuf);
// 发送数据
SendMsg(szSendBuf);
}

return 0;
}
BOOL Connection(char *lpszServerIp, int iServerPort)
{
// 初始化 Winsock 库
WSADATA wsaData = { 0 };
WSAStartup(MAKEWORD(2, 2), &wsaData);
// 创建流式套接字
g_ClientSocket = socket(AF_INET, SOCK_STREAM, 0);
if (INVALID_SOCKET == g_ClientSocket)
{
return FALSE;
}
// 设置服务端地址和端口信息
sockaddr_in addr = { 0 };
addr.sin_family = AF_INET;
addr.sin_port = htons(iServerPort);
addr.sin_addr.S_un.S_addr = inet_addr(lpszServerIp);
// 连接到服务器
if (0 != connect(g_ClientSocket, (sockaddr *)(&addr), sizeof(addr)))
{
return FALSE;
}
// 创建接收数据多线程
CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)RecvMsg, NULL, NULL, NULL);

return TRUE;
}


// 发送数据
void SendMsg(char *pszSend)
{
// 发送数据
send(g_ClientSocket, pszSend, (1 + lstrlen(pszSend)), 0);
printf("[send]%s\n", pszSend);
}


// 接收数据
void RecvMsg()
{
char szBuf[MAX_PATH] = { 0 };
while (TRUE)
{
// 接收数据
int iRet = recv(g_ClientSocket, szBuf, MAX_PATH, 0);
if (0 >= iRet)
{
continue;
}
printf("[recv]%s\n", szBuf);
}
}