
实现的编译器是 Visual Studio 2010, 之前用的2022太新,一些头文件用不了
写的过程中对数据在传输层的通讯 ACK TCP 协议都有了新的理解
服务端和客户端分开两个project:运行注意事项:
// Server.cpp : create a console application, and include the sources in the project
//
// 1. open the *.c in the Visual C++, then “rebuild all”.
// 2. click “yes” to create a project workspace.
// 3. You need to -add the library ‘ws2_32.lib’ to your project
// (Project -> Properties -> Linker -> Input -> Additional Dependencies)
// 4. recompile the source.
代码
Server:
// You need to -add the library ‘ws2_32.lib’ to your project
#include “stdafx.h”
#include
#include
#include
#include
#define DEFAULT_PORT 5019//持续监听5019端口
int main(int argc, char **argv){
char szBuff[100];//The information of the message need to transimit
int msg_len;//the length of the message
int addr_len;//the length of the address
struct sockaddr_in local, client_addr;
SOCKET sock, msg_sock;
WSADATA wsaData;
//514
if (WSAStartup(0x202, &wsaData) == SOCKET_ERROR){
// stderr: standard error are printed to the screen.
fprintf(stderr, "WSAStartup failed with error %d\n", WSAGetLastError());
//WSACleanup function terminates use of the Windows Sockets DLL.
WSACleanup();
return -1;
}
// Fill in the address structure
local.sin_family = AF_INET;
local.sin_addr.s_addr = INADDR_ANY;
local.sin_port = htons(DEFAULT_PORT);
// protocol family:AF_INET, the type of protocol:SOCK_STREAM , When it is equal to 0, choose the type equal the type of protocols
sock = socket(AF_INET,SOCK_STREAM, 0); //TCP socket
if (sock == INVALID_SOCKET){
fprintf(stderr, "socket() failed with error %d\n", WSAGetLastError());
WSACleanup();
return -1;
}
// bind: int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen)
// the bind () function is to bind a name to this sock
if (bind(sock, (struct sockaddr *)&local, sizeof(local)) == SOCKET_ERROR){
fprintf(stderr, "bind() failed with error %d\n", WSAGetLastError());
WSACleanup();
return -1;
}
//waiting for the connections
//listen function() is used to see whether there is a user connected done,5 is the most acceptable devices can be taken.
if (listen(sock, 5) == SOCKET_ERROR){
fprintf(stderr, "listen() failed with error %d\n", WSAGetLastError());
WSACleanup();
return -1;
}
//收到连接信息,则接收消息,并返回消息
printf("Waiting for connections ........\n");
addr_len = sizeof(client_addr);
//accept function is int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen); //返回连接connect_fd
//监听套接字,accept返回一个套接字,用此完成与client的通信
msg_sock = accept(sock, (struct sockaddr*)&client_addr, &addr_len);
if (msg_sock == INVALID_SOCKET){
fprintf(stderr, "accept() failed with error %d\n", WSAGetLastError());
WSACleanup();
return -1;
}
printf("accepted connection from %s, port %d\n",inet_ntoa(client_addr.sin_addr),htons(client_addr.sin_port));
while(1){
//调用网络I/O进行读写 *** 作,recieve
msg_len = recv(msg_sock, szBuff, sizeof(szBuff), 0);
if (msg_len == SOCKET_ERROR){
fprintf(stderr, "recv() failed with error %d\n", WSAGetLastError());
WSACleanup();
return -1;
}
//use three times closesocket() can close the connection
if (msg_len == 0){
printf("Client closed connection\n");
closesocket(msg_sock);
return -1;
}
printf("Bytes Received: %d, message: %s from %s\n", msg_len, szBuff, inet_ntoa(client_addr.sin_addr));
//recv/send
msg_len = send(msg_sock, szBuff, sizeof(szBuff), 0);
if (msg_len == 0){
printf("Client closed connection\n");
closesocket(msg_sock);
return -1;
}
} //end of while loop
closesocket(msg_sock);
WSACleanup();
}
Client:
#include “stdafx.h”
#include
#include
#include
#include
#define DEFAULT_PORT 5019//定义端口号,需要后期在dos 命令窗口输入方可运行
int main(int argc, char **argv){
char szBuff[100];
int msg_len;
//int addr_len;
struct sockaddr_in server_addr;
struct hostent *hp;
SOCKET connect_sock;
WSADATA wsaData;
char *server_name = "localhost";
unsigned short port = DEFAULT_PORT;
unsigned int addr;
if (argc != 3){
printf("echoscln [server name] [port number]\n");
return -1;
}
else{
server_name = argv[1];
port = atoi(argv[2]);
}
if (WSAStartup(0x202, &wsaData) == SOCKET_ERROR){
// stderr: standard error are printed to the screen.
fprintf(stderr, "WSAStartup failed with error %d\n", WSAGetLastError());
//WSACleanup function terminates use of the Windows Sockets DLL.
WSACleanup();
return -1;
}
if (isalpha(server_name[0]))
hp = gethostbyname(server_name);
else{
addr = inet_addr(server_name);
hp = gethostbyaddr((char*)&addr, 4, AF_INET);
}
if (hp==NULL)
{
fprintf(stderr, "Cannot resolve address: %d\n", WSAGetLastError());
WSACleanup();
return -1;
}
//copy the resolved information into the sockaddr_in structure
memset(&server_addr, 0, sizeof(server_addr));
memcpy(&(server_addr.sin_addr), hp->h_addr, hp->h_length);
server_addr.sin_family = hp->h_addrtype;
server_addr.sin_port = htons(port);
connect_sock = socket(AF_INET,SOCK_STREAM, 0); //TCP socket
if (connect_sock == INVALID_SOCKET){
fprintf(stderr, "socket() failed with error %d\n", WSAGetLastError());
WSACleanup();
return -1;
}
printf("Client connecting to: %s\n", hp->h_name);
//socket 客户端描述字, the address of the socket sever, the legth of the socket address
if (connect(connect_sock, (struct sockaddr *)&server_addr, sizeof(server_addr)) == SOCKET_ERROR){
fprintf(stderr, "connect() failed with error %d\n", WSAGetLastError());
WSACleanup();
return -1;
}
//开始实现通讯功能
while(1){
printf("input character string:\n");
gets(szBuff);
msg_len = send(connect_sock, szBuff, sizeof(szBuff), 0);
if (msg_len == SOCKET_ERROR){
fprintf(stderr, "send() failed with error %d\n", WSAGetLastError());
WSACleanup();
return -1;
}
if (msg_len == 0){
printf("server closed connection\n");
closesocket(connect_sock);
WSACleanup();
return -1;
}
msg_len = recv(connect_sock, szBuff, sizeof(szBuff), 0);
if (msg_len == SOCKET_ERROR){
fprintf(stderr, "send() failed with error %d\n", WSAGetLastError());
closesocket(connect_sock);
WSACleanup();
return -1;
}
if (msg_len == 0){
printf("server closed connection\n");
closesocket(connect_sock);
WSACleanup();
return -1;
}
printf("Echo from the server %s.\n", szBuff);
}//end of while loop
//FIN package, used to close the package
closesocket(connect_sock);
WSACleanup();
}
测试的时候应该用两台电脑,一台server一台client。
当时我就用了一台,运行前把exe文件拖入dos命令窗口,输入IP地址与端口号
效果如图:
看到一个dos命令窗口发的讯息 另一个窗口是能接收到的
如果学习路上的你对这个模块还有什么疑问,欢迎随时评论区留言交流,我看到都会回复
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)