C语言网络编程总结(IPv4与TCP)
server 和 client对socket的处理
server : 端口号码 numero of port
client :server的ip地址,以及开放的端口号码
socket()->IPv4 +TCP
<sys/types.h>
<sys/socket.h>
3个parameters,
domaine: AF_INET -> IPv4
type: SOCKET_STREAM
protocole: 当domaine有多种选择的时候需要填写,在TCP/IP下,一般为0
返还值: int, value of description
注:第一个socket的值是3,第二个是4,那么0,1和2是什么呢?
0:stdin, 1:stdout, 2:stderr.
错误的返还值为负值,可以用下面的code来处理
int reuse = 1;
setsockopt(descripteurOfSocket, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse));
structure sockaddr和structure sockaddr_in
struct sockaddr是一个很模糊的结构
struct sockaddr
{
u_short sa_family;
char sa_data[14];
};
相比之下,struct sockaddr_in的结构更易于操作。但是在API Socket的使用中paramter是struct sockaddr,在构建之后要用(struct sockaddr)来强制转换
<netinet/in.h>
struct sockaddr_in
{
short sin_family;
u_short sin_port;
struct in_addr sin_addr;
char sin_zero[8];
};
注:在创建struct socketaddr_in之后需要清零
struct sockaddr_in my_addr;
memset((char*)&my_addr, 0, sizeof(my_addr));//<string.h>
在struct sockaddr_in的初始化中需要初始化sin_family, sin_port, sin_addr这三个参数。
sin_family: socket里的domaine值
sin_port:server开放的借口
sin_addr:只需要初始化sin_addr.s_addr即可。
比如
my_addr.sin_addr.s_addr=INADDR_ANY //任意可用接口IP为 0.0.0.0
//或者 INADDR_LOOPBACK 表示本地连接 127.0.0.1
网络格式(大端)
大端和小端是两种在储存上互为颠倒的格式,
这里是详细解释
网络上通常使用大端,而我们的电脑根据处理器有不同的情况,但一般是小端。
在
int htonl(int host_long) // format machine -> format web
int htons(int host_short)
int ntohl(int host_long) // format web -> format machine
int htohs(int host_short)
另外我们平时的IP地址格式是小端,所以应该用这里的函数转化成大端再写入struct sockaddr_in(这里面所有的值都应该是大端模式的)
介绍预备知识,进入server和client
代码
server:
#include <sys/socket.h>
#include <stdio.h>
#include <sys/types.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h> //pour la fonction memset() //
#include <netinet/in.h> //pour la structure sockaddr_in//
#include <arpa/inet.h>
int main(String args[]){
int reuse = 1;
int sock;
char* buffer;
buffer =malloc(100*sizeof(char));
sock = socket(AF_INET,SOCK_STREAM,0);
setsockopt(sock, SOL_SOCKET, SO_REUSEADDR,&reuse, sizeof(reuse)) ;
int nbConnexion = 10;
int acc;
struct sockaddr_in client_addr;
struct sockaddr_in my_addr;
memset((char*)&my_addr,0,sizeof(my_addr));
my_addr.sin_family = AF_INET;
my_addr.sin_port = htons(8080);
my_addr.sin_addr.s_addr= INADDR_ANY;
//inet_aton("127.0.0.1", &(my_addr.sin_addr));
bind(sock, (struct sockaddr *)&my_addr, sizeof(my_addr));
listen(sock, nbConnexion);
int clilen= sizeof(client_addr);
acc = accept( sock, (struct sockaddr *)&client_addr, &clilen );
printf("IP du cilent est: %d\n",htonl(client_addr.sin_addr.s_addr));
printf("port du cilent est: %d\n",ntohs(client_addr.sin_port));
//la boucle infinie//
while (nbConnexion>0){
memset(buffer,0,100);
read(acc,buffer,100);
printf("%s\n",buffer);
write(acc, buffer,100);
nbConnexion--;
printf("nb de connexions qui restent %d\n", nbConnexion);
}
close(sock);
return 0;
}
client:
#include <sys/socket.h>
#include <stdio.h>
#include <sys/types.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h> //pour la fonction memset() //
#include <netinet/in.h> //pour la structure sockaddr_in//
#include <arpa/inet.h>
int main(String args[]){
int nb = 0;
char* buffer;
buffer = malloc(100*sizeof(char));
int sock;
sock = socket(AF_INET,SOCK_STREAM,0);
//CLIENT --- sert a rien //
struct sockaddr_in client_addr;
memset((char*)&client_addr,0,sizeof(client_addr));
client_addr.sin_port = htons(80);
client_addr.sin_family = AF_INET;
inet_aton("0.0.0.0", &(client_addr.sin_addr));
//SERVEUR//
struct sockaddr_in my_addr;
memset((char*)&my_addr,0,sizeof(my_addr));
my_addr.sin_port = htons(8080);
my_addr.sin_family = AF_INET;
inet_aton("127.0.0.1", &(my_addr.sin_addr));
connect(sock, (struct sockaddr *)&my_addr, sizeof(my_addr));
while(nb<10){
printf("saisir la phrase \n");
memset(buffer,0,100);
fgets(buffer,100,stdin);
write(sock, buffer, 100);
memset(buffer,0,100);
read(sock,buffer,100);
printf("%s\n",buffer);
nb ++;
}
close(sock);
return 0;
}