c TCPサーバ及びクライアント
13652 ワード
一、TCP/IPネットワークプログラミングの予備知識
1、socket 1、特殊なファイル記述子:ファイルの形式で操作することができ、異なるプロセス間のインタラクションを実現することができる2、1つの関数(関数は特殊なファイルを作成するために使用される)3、接続向けまたは無接続2、IPアドレスは対端のアドレス3を得ることができ、ポート番号はサーバーまたはカスタマーサービス側が実行するプロセス4、バイト順の2種類の記憶方式である:大端記憶、小端記憶小端記憶:データの低位記憶は低アドレス方向大端記憶、データの高位記憶は低アドレス方向二、socketタイプ1、フローソケット(TCP/IP)2、データレポートソケット(UDP)3、元ソケット三、ネットワークプログラミング常用関数1、socket()ヘッダファイル:#include/*See NOTES*/#include
関数プロトタイプ:int socket(int domain,int type,int protocol);パラメータ1:domain:アドレスファミリーAF_UNIX, AF_LOCAL Local communication unix(7) AF_INET IPv4 Internet protocols ip(7) AF_INET 6 IPv 6パラメータ2:type:ソケットタイプSOCK_STREAM SOCK_DGRAM SOCK_SEQACK ETパラメータ3:protocol:通常02、bind()ヘッダファイル:#include/*See NOTES*/#include関数プロトタイプ:int bind(int sockfd、const struct sockaddr*addr、socklen_t addrlen);パラメータ1,sockfd:socket関数呼び出し返されるファイル記述子パラメータ2,構造体のアドレスパラメータ3,addrlen:sockaddrアドレス構造の長さ3,listen()ヘッダファイル:#include/*See NOTES*/#include
関数プロトタイプ:int listen(int sockfd,int backlog);パラメータ1,sockfd:socket関数呼び出し返されるファイル記述子パラメータ2,backlog:定義キューの最大長4,accept()ヘッダファイル:#include/*See NOTES*/#include
関数プロトタイプ:int accept(int sockfd,struct sockaddr*addr,socklen_t*addrlen);パラメータ1,sockfd:socket関数呼び出し返されるファイル記述子パラメータ2,addr:構造体のアドレスパラメータ3,addrlen:sockaddrアドレス構造の長さのアドレス戻り値:新しいsocketファイル記述子5,connect()ヘッダファイル:#include/*See NOTES*/#include関数プロトタイプ:int connect(int sockfd,const struct sockaddr*addr,socklen_t addrlen);パラメータ1,sockfd:socket関数呼び出し返されるファイル記述子パラメータ2,構造体のアドレスパラメータ3,addrlen:sockaddrアドレス構造の長さ6,send()/recv()/write()この2つの関数は受信と送信を表す.TCP/IPサーバ1、リスニングソケットの作成socket()関数2、バインドipおよびポートbind()関数3、リスニングの開始listen()関数4、accept()関数の開始5、データの送受信read()/write()の2つの関数は、受信および送信を表す.TCP/IPクライアント1、ソケットソケットの作成()2、接続サーバconnect()3、送受信データread()/write()の2つの関数は、受信と送信を表します.
サーバとクライアントの3回の握手:
最初の握手:クライアントは接続の確立要求を開始し、SYNとシーケンス番号iを送信する.
2回目の握手:サーバはクライアントとの接続を確認し、SYNと独自のシリアル番号jを送信し、ACKと確認値i+1を同時に送信する
3回目の握手:クライアントはサーバにACKおよび確認値j+1を送信する
サーバとクライアントの手を4回振る:
最初の手を振る:アクティブに切断する側は接続を閉じることを要求して、そしてFINを送信します
2回目の手を振る:パッシブブレーク側確認クローズ接続送信ACKと確認値i+2
3回目の手を振る:受動的に切断した方がFINを送信します
4回目の手を振る:自発的に切る方がACKと確認値J+2を送って確認を表す
サーバ
クライアント
1、socket 1、特殊なファイル記述子:ファイルの形式で操作することができ、異なるプロセス間のインタラクションを実現することができる2、1つの関数(関数は特殊なファイルを作成するために使用される)3、接続向けまたは無接続2、IPアドレスは対端のアドレス3を得ることができ、ポート番号はサーバーまたはカスタマーサービス側が実行するプロセス4、バイト順の2種類の記憶方式である:大端記憶、小端記憶小端記憶:データの低位記憶は低アドレス方向大端記憶、データの高位記憶は低アドレス方向二、socketタイプ1、フローソケット(TCP/IP)2、データレポートソケット(UDP)3、元ソケット三、ネットワークプログラミング常用関数1、socket()ヘッダファイル:#include/*See NOTES*/#include
関数プロトタイプ:int socket(int domain,int type,int protocol);パラメータ1:domain:アドレスファミリーAF_UNIX, AF_LOCAL Local communication unix(7) AF_INET IPv4 Internet protocols ip(7) AF_INET 6 IPv 6パラメータ2:type:ソケットタイプSOCK_STREAM SOCK_DGRAM SOCK_SEQACK ETパラメータ3:protocol:通常02、bind()ヘッダファイル:#include/*See NOTES*/#include関数プロトタイプ:int bind(int sockfd、const struct sockaddr*addr、socklen_t addrlen);パラメータ1,sockfd:socket関数呼び出し返されるファイル記述子パラメータ2,構造体のアドレスパラメータ3,addrlen:sockaddrアドレス構造の長さ3,listen()ヘッダファイル:#include/*See NOTES*/#include
関数プロトタイプ:int listen(int sockfd,int backlog);パラメータ1,sockfd:socket関数呼び出し返されるファイル記述子パラメータ2,backlog:定義キューの最大長4,accept()ヘッダファイル:#include/*See NOTES*/#include
関数プロトタイプ:int accept(int sockfd,struct sockaddr*addr,socklen_t*addrlen);パラメータ1,sockfd:socket関数呼び出し返されるファイル記述子パラメータ2,addr:構造体のアドレスパラメータ3,addrlen:sockaddrアドレス構造の長さのアドレス戻り値:新しいsocketファイル記述子5,connect()ヘッダファイル:#include/*See NOTES*/#include関数プロトタイプ:int connect(int sockfd,const struct sockaddr*addr,socklen_t addrlen);パラメータ1,sockfd:socket関数呼び出し返されるファイル記述子パラメータ2,構造体のアドレスパラメータ3,addrlen:sockaddrアドレス構造の長さ6,send()/recv()/write()この2つの関数は受信と送信を表す.TCP/IPサーバ1、リスニングソケットの作成socket()関数2、バインドipおよびポートbind()関数3、リスニングの開始listen()関数4、accept()関数の開始5、データの送受信read()/write()の2つの関数は、受信および送信を表す.TCP/IPクライアント1、ソケットソケットの作成()2、接続サーバconnect()3、送受信データread()/write()の2つの関数は、受信と送信を表します.
サーバとクライアントの3回の握手:
最初の握手:クライアントは接続の確立要求を開始し、SYNとシーケンス番号iを送信する.
2回目の握手:サーバはクライアントとの接続を確認し、SYNと独自のシリアル番号jを送信し、ACKと確認値i+1を同時に送信する
3回目の握手:クライアントはサーバにACKおよび確認値j+1を送信する
サーバとクライアントの手を4回振る:
最初の手を振る:アクティブに切断する側は接続を閉じることを要求して、そしてFINを送信します
2回目の手を振る:パッシブブレーク側確認クローズ接続送信ACKと確認値i+2
3回目の手を振る:受動的に切断した方がFINを送信します
4回目の手を振る:自発的に切る方がACKと確認値J+2を送って確認を表す
サーバ
#include
#include
#include <string.h>
#include
#include
#include
#include in.h>
#include
#include
int main()
{
int listenfd,connfd;
int listenfd = socket(AF_INET,SOCK_STREAM,0);
if(listenfd == -1)
{
perror("socket");
return -1;
}
int on = 1;
int ret = setsockopt(listenfd,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(on));
if(-1 == ret){
perror("setsockopt");
return -1;
}
struct sockaddr_in saddr,caddr;
saddr.sin_family = AF_INET;
saddr.sin_port = htons(8888);
//
saddr.sin_addr.s_addr = htonl(INADDR_ANY);
//
//saddr.sin_addr.s_addr = inet_addr("127.0.0.1");
ret = bind(listenfd,(struct sockaddr *)(&saddr),sizeof(saddr));
if(-1 == ret){
perror("bind");
return -1;
}
ret = listen(listenfd, 5);
if(-1 == ret){
perror("listen");
return -1;
}
char buf[1024];
addrlen = sizeof(caddr);
while(1)
{
connfd = accept(listenfd, (struct sockaddr *)&caddr, &addrlen);
if(-1 == ret){
perror("accept");
return -1;
}
inet_ntop(AF_INET,&caddr.sin_addr,cip,INET_ADDRSTRLEN);
printf("client ip = %s, port = %d
",cip,ntohs(caddr.sin_port)); // ip
memset(buf,0,sizeof(buf));
ret = read(connfd, buf, sizeof(buf));
if(-1 == ret){
perror("read");
return -1;
}
ret = write(connfd,buf,sizeof(buf));
if(-1 == ret){
perror("write");
return -1;
}
}
}
クライアント
#include
#include
#include <string.h>
#include
#include
#include
#include in.h>
#include
#include
int main()
{
char buf[1024];
int sockfd;
struct sockaddr_in saddr;
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if(-1 == sockfd){
perror("socket");
return -1;
}
saddr.sin_family = AF_INET;
saddr.sin_port = htons(8888);
saddr.sin_addr.s_addr = htonl(INADDR_ANY);
int ret = connect(sockfd, (struct sockaddr *)&saddr, sizeof(saddr));
if(-1 == ret){
perror("connect");
return -1;
}
while(1)
{
memset(buf, 0 , sizeof(buf));
scanf("%s", buf);
ret = write(sockfd, buf, sizeof(buf));
if(-1 == ret)
{
perror("write");
return -1;
}
ret = read(sockfd, buf, sizeof(buf));
if(-1== ret){
perror("read");
return -1;
}
printf("buf = %s
",buf);
}
}