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;
}