断开套接字连接

1、关闭连接

Linux的close函数和Windows的closesockt函数意味着完全断开连接,完全断开连接不仅指无法发送数据而且指无法接受数据。因此,必须要能够断开一部分连接才行,关闭数据流的一部分。

2、半关闭的函数

#include<sys/socket.h>

int shutdown(int sock, int howto) ;

sock:需要断开的套接字文件描述符;

howto:传递断开方式信息,SHUT_RD断开输入流,SHUT_WR断开输出流,SHUT_RDWR同时断开IO流;

#include <winsock2.h>

int shutdown(SOCKET sock, int howto);

sock:需要断开的套接字文件描述符;

howto:传递断开方式信息,SD_EWCEIVE断开输入流,SD_SEND断开输出流,SD_BOTH同时断开IO流;

3.实例

服务器端程序 

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <WinSock2.h>

#define BUF_SIZE 30
void ErrorHandling(char *message)
{
	fputs(message, stderr);
	fputc('\n', stderr);
	exit(1);
}

int main(int argc, char *argv[])
{
	WSADATA wsaData;
	SOCKET hservSock, hclntSock;
	FILE *fp;
	char buf[BUF_SIZE];
	int readCnt;

	SOCKADDR_IN servAddr, clntAddr;
	int clntAdrSz;

	if (argc != 2)
	{
		printf("参数不足");
		exit(0);
	}
	if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
		ErrorHandling("WSAStartup() Error");

	fp = fopen("file_server_win.c", "rb");
	hservSock = socket(PF_INET, SOCK_STREAM, 0);

	memset(&servAddr, 0, sizeof(servAddr));
	servAddr.sin_family = AF_INET;
	servAddr.sin_addr.s_addr = htonl(INADDR_ANY);
	servAddr.sin_port = htons(atoi(argv[1]));

	bind(hservSock, (SOCKADDR*)&servAddr, sizeof(servAddr));//绑定套接字
	listen(hservSock, 5);
	
	clntAdrSz = sizeof(clntAddr);
	hclntSock = accept(hservSock, (SOCKADDR*)&clntAddr, &clntAdrSz); //返回客户端套接字

	//服务器端不断发生数据
    while (1)    
	{
		readCnt = fread((void*)buf, 1, BUF_SIZE, fp);
		if (readCnt < BUF_SIZE)
		{
			send(hclntSock, (char*)&buf, readCnt, 0);
			break;
		}
		send(hclntSock, (char*)&buf, readCnt, 0);
	}

	shutdown(hclntSock, SD_SEND);//数据发生完毕关闭服务器端的发送数据流
	recv(hclntSock, (char*)buf, BUF_SIZE, 0);//服务器正常接收数据
	printf("Message from client:%s\n", buf);

	fclose(fp);
	closesocket(hclntSock);
	closesocket(hservSock);
	WSACleanup();

	system("Pause");
	return 0;
}

客户端程序

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <WinSock2.h>            //windows平台下包含的头文件

#define BUF_SIZE 30
void ErrorHandling(char *message)
{
	fputs(message, stderr);
	fputc('\n', stderr);
	exit(1);
}

int main(int argc, char *argv[])
{
	WSADATA wsaData;
	SOCKET hSock;
	FILE *fp;
	char buf[BUF_SIZE];
	int readCnt;

	SOCKADDR_IN servAddr;
	int clntAdrSz;

	if (argc != 3)
	{
		printf("参数不足");
		exit(0);
	}
	if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) //windows平台下进行的初始化
		ErrorHandling("WSAStartup() Error");

	fp = fopen("file_server_win.c", "rb");
	hSock = socket(PF_INET, SOCK_STREAM, 0);       //创建客户端套接字

	memset(&servAddr, 0, sizeof(servAddr));        //分配IP地址和端口号
	servAddr.sin_family = AF_INET;
	servAddr.sin_addr.s_addr = htonl(INADDR_ANY);
	servAddr.sin_port = htons(atoi(argv[1]));

	connect(hSock, (SOCKADDR*)&servAddr, sizeof(servAddr));//连接服务器

	while (readCnt=recv(hSock, buf, BUF_SIZE, 0) != 0)
	{
		fwrite((void*)buf, 1, readCnt, fp);
	}

	puts("Receive file data");
	send(hSock, "Thank you", 10, 0);

	fclose(fp);
	closesocket(hSock);    //关闭套接字
	WSACleanup();

	system("Pause");
	return 0;
}

猜你喜欢

转载自blog.csdn.net/u012967763/article/details/82982892
今日推荐