简单的网络服务器(简单的TCP,简单的UDP,多进程多线程TCP)
来源:互联网 发布:物流信息化软件 编辑:程序博客网 时间:2024/05/21 13:21
网路编程接口:
(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;}
后续还会有高效的服务器,
- 简单的网络服务器(简单的TCP,简单的UDP,多进程多线程TCP)
- 【网络】实现简单的TCP、UDP服务器、TCP多进程/多线程服务器
- 简单的网络编程学习TCP/UDP
- 简单的多线程的TCP服务器代码
- 简单的TCP服务器
- 简单的TCP服务器
- 简单的TCP/UDP程序
- QT 简单的网络通信(tcp ,udp)
- TCP服务器多线程 多进程简单测试
- python socket实现简单的(TCP/UDP)服务器/客户端
- 【网络】常见通信协议HTTP、TCP、UDP的简单介绍
- 网络编程UDP和TCP的简单使用
- 一、简单的TCP服务器
- 基于TCP的简单服务器
- 简单的TCP客户-服务器
- 一个简单的TCP服务器
- 简单的TCP网络连接
- <网络编程培训之三> 实现TCP/UDP的简单Echo服务器
- runtimeException也是能够捕获的
- linux下gdb的安装方法
- shadowmap、深度、projector阴影技术
- springMVC操作数据库 DAO访问数据对象
- 腾讯2017年实习生春招面试记录
- 简单的网络服务器(简单的TCP,简单的UDP,多进程多线程TCP)
- Vue 自定义指令(拖拽,右键菜单)
- gpmc
- SIP穿越NAT的rport机制
- codeforces——732A——Buy a Shovel
- android桌面悬浮小窗的实现--FloatingView
- php_crond:一个基于pcntl的定时任务系统-支持秒粒度的任务配置
- java基础-面向对象一
- 从零开始学sklearn