网路编程接口:
(1)int socket(int domain, int type,int protocol)
domain:说明我们网络程序所在的主机采用的通讯协族(AF_UNIX和AF_INET等).
type:我们网络程序所采用的通讯协议(SOCK_STREAM,SOCK_DGRAM等)
protocol:由于我们指定了type,所以这个地方我们一般只要用0来代替就可以了
socket为网络通讯做基本的准备.成功时返回文件描述符,失败时返回-1,看errno可知道出错的详细情况
(2)int bind(int sockfd, struct sockaddr *my_addr, int addrlen)
sockfd:是由socket调用返回的文件描述符.
addrlen:是sockaddr结构的长度.
my_addr:是一个指向sockaddr的指针. 在中有 sockaddr的定义
struct sockaddr{
unisgned short as_family;
char sa_data[14];
};
socket为实现泛型编程,把struct sockaddr可以类似我们的void
一般使用另外一个结构(struct sockaddr_in) 来代替.在中有sockaddr_in的定义
struct sockaddr_in{
unsigned short sin_family;
unsigned short int sin_port;
struct in_addr sin_addr;
unsigned char sin_zero[8];}
我们主要使用Internet所以sin_family一般为AF_INET(IPv4),sin_addr设置为INADDR_ANY表示可以和任何的主机通信,sin_port是我们要监听的端口号.sin_zero[8]是用来填充的.
bind将本地的端口同socket返回的文件描述符捆绑在一起.成功是返回0,失败的情况和socket一样
(3)int listen(int sockfd,int backlog)
sockfd:是bind后的文件描述符.
backlog:设置请求排队的最大长度.当有多个客户端程序和服务端相连时, 使用这个表示可以介绍的排队长度. listen函数将bind的文件描述符变为监听套接字.返回的情况和bind一样.
(4)int accept(int sockfd, struct sockaddr *addr,int *addrlen)
sockfd:是listen后的文件描述符.
addr,addrlen是用来给客户端的程序填写的,服务器端只要传递指针就可以了. bind,listen和accept是服务器端用的函数,accept调用时,服务器端的程序会一直阻塞到有一个客户程序发出了连接. accept成功时返回最后的服务器端的文件描述符,这个时候服务器端可以向该描述符写信息了. 失败时返回-1
(4)int connect(int sockfd, struct sockaddr * serv_addr,int addrlen)
sockfd:socket返回的文件描述符.
serv_addr:储存了服务器端的连接信息.其中sin_add是服务端的地址
addrlen:serv_addr的长度
(5)connect函数是客户端用来同服务端连接的.成功时返回0,sockfd是同服务端通讯的文件描述符失败时返回-1
总的来说网络程序是由两个部分组成的–客户端和服务器端.它们的建立步骤一般是:
服务器端
socket–>bind–>listen–>accept
客户端
socket–>connect
代码1:客户端:
int main(int argc,char* argv[])
{
if(argc!=3)
{
printf("Usge:%s [server_ip][server_port]\n");
exit(0);
}
int sock=socket(AF_INET,SOCK_STREAM,0);
if(sock<0)
{
perror("socket");
exit(1);
}
struct sockaddr_in server;
server.sin_family=AF_INET;
server.sin_port=htons(atoi(argv[2]));
server.sin_addr.s_addr=inet_addr(argv[1]);
ssize_t con=connect(sock,(struct sockaddr*)& server,sizeof(server));
if(con<0)
{
perror("connect faliur");
exit(2);
}
else
{
char buf[1024];
ssize_t s;
while(1)
{
s=read(0,buf,sizeof(buf));
if(s>0)
{
buf[s-1]=0;
write(sock,buf,sizeof(buf));
s=read(sock,buf,sizeof(buf));
if(s>0)
{
buf[s]=0;
printf("server each# %s\n",buf);
}
}
}
}
return 0;
}
代码2:简单的TCP服务器(服务一个客户)
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
#include<stdio.h>
#include <arpa/inet.h>
#include<stdlib.h>
#include <netinet/in.h>
#include<string.h>
int StatUp(const char*ip,int port)
{
int sock=socket(AF_INET,SOCK_STREAM,0);
if(sock<0)
{
perror("socket");
exit(1);
} #include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
#include<stdio.h>
#include <arpa/inet.h>
#include<stdlib.h>
#include <netinet/in.h>
#include<string.h>
void Usege(char* proc)
{
printf("usege:%s [server_ip][server_port]",proc);
}
int main(int argc,char*argv[])
{
if(argc!=3)
{
Usege(argv[0]);
return 0;
}
int sock=socket(AF_INET,SOCK_STREAM,0);
struct sockaddr_in server;
server.sin_family=AF_INET;
server.sin_port=htons(atoi(argv[2]));
server.sin_addr.s_addr=inet_addr(argv[1]);
int c=connect(sock,(struct sockaddr*)&server,sizeof(server));
if(c<0)
{
perror("connect");
exit(0);
}
else{
printf("please Enter#");
while(1)
{
char buf[1024];
ssize_t s=read(0,buf,sizeof(buf));
if(s>0)
{ buf[s-1]=0;
write(sock,buf,sizeof(buf));
s=read(sock,buf,sizeof(buf));
if(s>0)
{
buf[s]=0;
printf("server Echo#%s\n",buf);
}
}
}
}
close(sock);
return 0;
}
struct sockaddr_in local;
local.sin_family=AF_INET;
local.sin_port=htons(port); //open server,in local input port changer to inet's
local.sin_addr.s_addr=inet_addr(ip);
int b= bind( sock, (struct sockaddr*)&local,sizeof(local));
if(b<0)
{
perror("bind");
exit(2);
}
if(0>listen(sock,10))
{
perror("listen");
exit(3);
}
return sock;
}
void Usge( char* proc)
{
printf("%s [server_ip][server_port]\n",proc);
}
int main(int argc,char* argv[])
{
if(argc!=3)
{
Usge(argv[0]);
return 1;
}
int lisent_sock=StatUp(argv[1],atoi(argv[2]));
struct sockaddr_in client;
socklen_t len;
while(1)
{
int connected_sock=accept(lisent_sock,(struct sockaddr*)&client,&len); //connected ,client is a return's type parameter
if(connected_sock<0)
{
perror("accept");
continue;
}
else
{
printf("client:ip:%s port:%d is connected\n",inet_ntoa(client.sin_addr),ntohs(client.sin_port));
while(1)
{
char buf[1024];
ssize_t s=read(connected_sock,buf,sizeof(buf));
if(s>0)
{
buf[s]=0;
printf("client say# %s\n",buf);
write(connected_sock,buf,strlen(buf));
}
if(s==0)
{
printf("client is quit\n");
close(connected_sock);
break;
}
}
}
}
return 0;
}
代码3:简单的UDP服务器
#include <sys/types.h>
#include<arpa/inet.h>
#include <sys/socket.h>
#include<string.h>
#include<stdio.h>
#include<stdlib.h>
int StatUp(const char* ip,int port)
{
int sock=socket(AF_INET,SOCK_DGRAM,0);
if(sock<0)
{
perror("socket");
exit(1);
}
struct sockaddr_in server;
server.sin_family=AF_INET;
server.sin_port=htons(port);
server.sin_addr.s_addr=inet_addr(ip);
int b=bind(sock,(struct sockaddr*)&server,sizeof(server));
if(b<0)
{
perror("bind");
exit(2);
}
return sock;
}
void Usge(char* proc)
{
printf("Usge:%s [server_ip][server_port]",proc);
}
int main(int argc,char * argv[])
{
if(argc!=3)
{
Usge(argv[0]);
exit(0);
}
int sock=StatUp(argv[1],atoi(argv[2]));
char buf[1024];
while(1)
{
struct sockaddr_in client;
socklen_t len=sizeof(client);
ssize_t s;
s=recvfrom(sock, buf, sizeof(buf), 0,(struct sockaddr *)&client, &len);
if(s<0)
{
perror("recvform");
}
else
{
if(s>0)
{ buf[s-1]=0;
printf("client:ip:%s ,port: %d",inet_ntoa(client.sin_addr),ntohs(client.sin_port));
buf[s]=0;
printf("client say#%s\n",buf);
sendto(sock,buf, sizeof(buf), 0,(struct sockaddr *)&client, len);
}
else
{
printf("client is quit|\n");
}
}
}
return 0;
}
代码4:多进程TCP服务器
#include<stdlib.h>
#include<stdio.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<unistd.h>
#include<string.h>
#include<arpa/inet.h>
#include <netinet/in.h>
int StatUp(const char *ip,int port)
{
int sock=socket(AF_INET,SOCK_STREAM,0);
if(sock<0)
{
perror("socket");
exit(1);
}
struct sockaddr_in local;
local.sin_family=AF_INET;
local.sin_port=htons(port);
local.sin_addr.s_addr=inet_addr(ip);
int b=bind(sock,(struct sockaddr*)&local,sizeof(local));
if(b<0)
{
perror("bind");
exit(2);
}
int li=listen(sock,10);
if(li<0)
{
perror("listen");
exit(3);
}
return sock;
}
int main(int argc,char* argv[])
{
if(argc!=3)
{
printf("Usge: %s [server_IP] [server_port]\n",argv[0]);
exit(0);
}
int listen_sock=StatUp(argv[1],atoi(argv[2]));
while(1)
{
struct sockaddr_in client;
socklen_t len=sizeof(client);
int connected_sock= accept(listen_sock,(struct sockaddr*)&client,&len);
if(connected_sock<0)
{
printf("connect failur\n");
continue;
}
if(connected_sock>0)
{
pid_t id=fork();
if(id<0)
{
perror("fock");
continue;
}
if(id==0)
{ //child;
while(1)
{
char buf[1024];
ssize_t s;
s= read(connected_sock,buf,sizeof(buf));
if(s==0)
{
printf("client: ip:%s port:%d",inet_ntoa(client.sin_addr),ntohs(client.sin_port));
printf("is qiuit\n");
close(connected_sock);
break;
}
if(s>0)
{
buf[s-1]=0;
printf("client: ip:%s port:%d",inet_ntoa(client.sin_addr),ntohs(client.sin_port));
printf("-say#%s\n",buf);
write(connected_sock,buf,sizeof(buf));
}
}
}
else
{ //father;
close(connected_sock); //******8 father's connnected rember cloase (must)
if(0<fork()) //fock again
exit(0) ;
}
}
}
return 0;
}
代码5.多线程TCP服务器
#include<stdlib.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<string.h>
#include<stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include<pthread.h>
void* handler(void* sockt)
{
printf("action");
int sock=*(int*)sockt;
int s;
char buf[1024];
while(1)
{
s=read(sock,buf,sizeof(buf)-1);
if(s==0)
break;
if(s>0)
{
buf[s-1]=0;
printf("client say:%s",buf);
fflush(stdout);
char* msg="wwwwwwww";
write(sock,msg,strlen(msg));
break;
}
if(s==0)
break;
}
printf("connect is break\n");
close(sock);
}
int StatUp(char * ip,int port)
{
int sock=socket(AF_INET,SOCK_STREAM,0);
if(sock<0)
{
perror("socket");
exit(4);
}
struct sockaddr_in local;
local.sin_family=AF_INET;
local.sin_port=htons(port);
local.sin_addr.s_addr=inet_addr(ip);
int b= bind(sock,(struct sockaddr*)&local,sizeof(local));
if(b<0)
{
perror("bind");
exit(5);
}
int li=listen(sock,10);
if(li<0)
{
perror("listen");
exit(6);
}
int opt=1;
setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt));
return sock;
}
/*int main(int argc,char *argv[])
{
if(argc!=3)
{
printf("Usage: %s[server_ip]{seerver_port]}");
return 1;
}
int listen_sock=StatUp(argv[1],atoi(argv[2]));
if(listen_sock<0)
{
perror("lisent");
exit(2);
}
struct sockaddr_in peer;
while(1)
{
socklen_t len;
int new_sock=accept(listen_sock,(struct sockaddr*)&peer,&len);
if(new_sock<0)
{
perror("accept");
continue;
}
printf("client ip:%s port:%d",inet_ntoa(peer.sin_addr),ntohs(peer.sin_port));
pthread_t id;
pthread_detach(id);
}
return 0;
}
*/
int main(int argc,char* argv[])
{
if(argc!=3)
{
printf("int put");
exit(1);
}
int listen_sock=StatUp(argv[1],atoi(argv[2]));
struct sockaddr_in peer;
while(1)
{
socklen_t len=sizeof(peer);
int new_sock=accept(listen_sock,(struct sockaddr*)&peer,&len);
if(new_sock<0)
{
printf("ssssssssssss");
perror("accept");
continue;
}
printf("client:ip %s port:%d\n",inet_ntoa(peer.sin_addr),ntohs(peer.sin_port));
pthread_t id;
pthread_create(&id,NULL,handler,(void*)&new_sock);
pthread_detach(id);
}
return 0;
}
后续还会有高效的服务器,