网络编程Socket之RST详解
产生RST的三个条件:
- 目的地为某端口的SYN到达,然而该端口上没有正在监听的服务器;
- TCP想取消一个已有的连接;
- TCP接收到一个根本不存在的连接上的分节;
现在模拟上面的三种情况:
client:

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <errno.h>
#define SERV_PORT 8000
int main()
{
struct sockaddr_in serverAdd;
bzero(&serverAdd, sizeof(serverAdd));
serverAdd.sin_family = AF_INET;
inet_pton(AF_INET, "127.0.0.1", &serverAdd.sin_addr);
serverAdd.sin_port = htons(SERV_PORT);
int connfd = socket(AF_INET, SOCK_STREAM, 0);
int connResult = connect(connfd, (struct sockaddr*) & serverAdd, sizeof(serverAdd));
if (connResult < 0)
{
printf("连接失败\n");
close(connfd);
return;
}
ssize_t writeLen;
char sendMsg[5000] = { 0 };
unsigned long long totalSize = 0;
while (1)
{
writeLen = write(connfd, sendMsg, sizeof(sendMsg));
if (writeLen < 0)
{
printf("发送失败");
return 0;
}
else
{
totalSize += writeLen;
printf("发送成功 totalSize = %zd\n", totalSize);
}
}
}
service:

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#define SERV_PORT 8000
int main(int argc, const char * argv[])
{
struct sockaddr_in serverAdd;
struct sockaddr_in clientAdd;
bzero(&serverAdd, sizeof(serverAdd));
serverAdd.sin_family = AF_INET;
serverAdd.sin_addr.s_addr = htonl(INADDR_ANY);
serverAdd.sin_port = htons(SERV_PORT);
socklen_t clientAddrLen;
int listenfd = socket(AF_INET, SOCK_STREAM, 0);
int yes = 1;
setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, (void *)&yes, sizeof(yes));
if (listenfd < 0)
{
printf("创建socket失败\n");
return -1;
}
int bindResult = bind(listenfd, (struct sockaddr *)&serverAdd, sizeof(serverAdd));
if (bindResult < 0)
{
printf("绑定端口失败\n");
close(listenfd);
return -1;
}
listen(listenfd, 20);
int connfd;
unsigned char recvMsg[246988];
unsigned long long totalSize = 0;
clientAddrLen = sizeof(clientAdd);
connfd = accept(listenfd,(struct sockaddr *)&clientAdd,&clientAddrLen);
if (connfd < 0)
{
printf("连接失败\n");
return -1;
}
else
{
// 这里我们用于测试,只接收一个连接
close(listenfd);
}
close(connfd);
return 0;
}
