c++ネットワークプログラミング(7)LINUXでのsocketプログラミングソケットベースの標準I/O関数使用とfopen,feof,fgets,fputs関数使用法
17823 ワード
原文作者:aircraft
テキストリンク:https://www.cnblogs.com/DOMLX/p/9614820.html
一.標準I/O
1,標準I/Oとは?実際には、fopen、feof、fgetc、fputsなどのC言語のファイル操作関数を指し、プラットフォームとは関係ありません.
2,ネットワーク通信で標準I/Oを使用するメリット:
3,ネットワーク通信で標準I/Oを使用する欠点:
4、変換関数
//ファイル記述子を標準I/O関数で使用するFILE構造体ポインタFILE*fdopen(int fildes,const char*mode)に変換する.成功時に変換されたFILE構造体ポインタを返し、失敗してNULLを返します.
//FILE構造体ポインタをファイル記述子int fileno(FILE*stream)に変換する.変換されたファイル記述子が正常に返され、-1が失敗しました.
注記:ソケットには標準I/Oが使われていますが、主に大量のデータを転送する必要がある場合に使われています.追加コードを書く必要があるため、想像していたほどよく使われていません.
fdopen関数の簡単な例を先に示します.
#include
main()
{
FILE * fp = fdopen(0, "w+");
fprintf(fp, "%s
", "hello!");
fclose(fp);
}
filenoの例:
#include
main()
{
FILE *fp;
int fd;
fp = fopen("/etc/passwd", "r");
fd = fileno(fp);
printf("fd = %d
", fd);
fclose(fp);
}
5.fgetsとfputs関数:
1.fgets()
機能:ファイルから文字列を読み込む
定義:char*fgets(char*s,int size,FILE*stream)説明:fgets()は、パラメータstreamが指すファイルから文字を読み込んでパラメータsが指すメモリ空間に格納するために使用されます.
改行文字まで読んだり、ファイルの最後まで読んだり、size-1文字まで読んだりするまで、最後にNULLを入れてファイルの最後にします.
戻り値:sのポインタが正常に返されませんでしたNULLの戻りに失敗しました
2.fputs()
機能:指定した文字列をファイルに書き込む
定義:char*fputs(const*char s,FILE*stream)説明:fputs()は、sが指す文字列をパラメータstreamが指すファイルに書き込むための戻り値です.書き込み文字列の個数を正常に返すと、EOFに戻りません.
サンプルコード:
include
int main()
{
int str[100];
fputs(fgets(str, 100, strin), strout);
return 0;
}
6.feof紹介:
1.stdio.hにおけるマクロ定義
#define _IOEOF 0x0010 #define feof(_stream) ((_stream)->_flag & _IOEOF)
2.feofの使用:
feofは検出ストリーム上のファイル終端子を使用し、その戻り値は2つあります.ファイル終端に遭遇した場合、関数値はゼロ値ではありません.そうしないと、関数値は0になります.
注:ここでのファイル終了フラグはEOF、EOFの16進コードは0 xFF(10進-1)で、テキストファイルに特化しています.テキストファイルにデータがASCIIコード値として格納されているため、普通文字のASCIIコードの範囲は32~127(10進)であり、EOFと衝突しないため、そのまま使用できます.ただし、バイナリファイルでは、データが-1になる可能性があるため、EOFでバイナリファイルの終了フラグとすることはできず、feof関数で判断できる.
これらの標準I/O関数の速度は通常の関数よりずっと速いことに注意しましたが、毎回使うわけではありません.
二.標準I/O関数に基づいてソケットサービスとクライアントの通信を実現
LINUXサービス:
#include
#include
#include <string.h>
#include
#include
#include
#define BUF_SIZE 1024
void error_handling(char *message);
int main(int argc, const char * argv[]) {
int serv_sock, clnt_sock;
char message[BUF_SIZE];
int str_len, i;
struct sockaddr_in serv_adr, clnt_adr;
socklen_t clnt_adr_sz;
FILE *readfp;
FILE *writefp;
if(argc != 2)
{
printf("Usage: %s
", argv[0]);
exit(1);
}
serv_sock = socket(PF_INET, SOCK_STREAM, 0);
if(serv_sock == -1)
error_handling("socket() error");
memset(&serv_adr, 0, sizeof(serv_adr));
serv_adr.sin_family = AF_INET;
serv_adr.sin_addr.s_addr = htonl(INADDR_ANY);
serv_adr.sin_port = htons(atoi(argv[1]));
if(bind(serv_sock, (struct sockaddr *) &serv_adr, sizeof(serv_adr)) == -1)
error_handling("bind() error");
if(listen(serv_sock, 5) == -1)
error_handling("listen() error");
clnt_adr_sz = sizeof(clnt_adr);
for (i = 0; i < 5; i++) {
clnt_sock = accept(serv_sock, (struct sockaddr *) &clnt_adr, &clnt_adr_sz);
if(clnt_sock == -1)
error_handling("accept() error");
else
printf("Connected client %d
", i+1);
// FILE
readfp = fdopen(clnt_sock, "r");
writefp = fdopen(clnt_sock, "w");
while (!feof(readfp))
{
// I/O
fgets(message, BUF_SIZE, readfp);// read,
fputs(message, writefp); // write,
fflush(writefp); // , ,
}
fclose(readfp);
fclose(writefp);
}
close(serv_sock);
return 0;
}
void error_handling(char *message)
{
fputs(message, stderr);
fputc('
', stderr);
exit(1);
}
LINUXのクライアント:
#include
#include
#include <string.h>
#include
#include
#include
#define BUF_SIZE 1024
void error_handling(char *message);
int main(int argc, const char * argv[]) {
int sock;
char message[BUF_SIZE];
int str_len;
struct sockaddr_in serv_adr;
FILE *readfp;
FILE *writefp;
if(argc != 3)
{
printf("Usage: %s
", argv[0]);
exit(1);
}
sock = socket(PF_INET, SOCK_STREAM, 0);
if(sock == -1)
error_handling("socket() error");
memset(&serv_adr, 0, sizeof(serv_adr));
serv_adr.sin_family = AF_INET;
serv_adr.sin_addr.s_addr = inet_addr(argv[1]);
serv_adr.sin_port = htons(atoi(argv[2]));
if (connect(sock, (struct sockaddr *) &serv_adr, sizeof(serv_adr)) == -1)
error_handling("connect() error");
else
puts("Connected ...............");
readfp = fdopen(sock, "r");
writefp = fdopen(sock, "w");
while (1)
{
fputs("Input message(Q to quit): ", stdout);
fgets(message, BUF_SIZE, stdin);
if (!strcmp(message, "q
") || !strcmp(message, "Q
"))
break;
fputs(message, writefp);
fflush(writefp);
fgets(message, BUF_SIZE, readfp);
printf("Message from server : %s", message);
}
fclose(writefp);
fclose(readfp);
return 0;
}
void error_handling(char *message)
{
fputs(message, stderr);
fputc('
', stderr);
exit(1);
}
最後に一言.このネットプログラミング入門シリーズのブログは連載学習で、興味があるのは私のブログの他の編を見ることができます...c++ネットワークプログラミングレッスン入門超詳細チュートリアル---ディレクトリ
さて今日はネットプログラミングの勉強はここで終わり、小さな飛行機は撤収してご飯を食べに行きます.、、多くの人は大学がすべてとても迷って何を学ぶのが良いことを知らないで、、、、、彼のを管理して、そんなに多く何を考えて、先に学んで更に言って、技术に対して偏见があるならば、それではあなたの领域はこれに限られます---
参考ブログ:https://blog.csdn.net/u010223072/article/details/48316117
参考ブログ:https://blog.csdn.net/qq_32103869/article/details/50834629
参考書:『TCP/IPネットワークプログラミング--尹聖雨』