资讯

精准传达 • 有效沟通

从品牌网站建设到网络营销策划,从策略到执行的一站式服务

TCP之socket编程-创新互联

socket(套接字):IP地址+端口号,唯一标识网络中的一个进程

十载的诸城网站建设经验,针对设计、前端、开发、售后、文案、推广等六对一服务,响应快,48小时及时工作处理。网络营销推广的优势是能够根据用户设备显示端的尺寸不同,自动调整诸城建站的显示方式,使网站能够适用不同显示终端,在浏览器中调整网站的宽度,无论在任何一种浏览器上浏览网站,都能展现优雅布局与设计,从而大程度地提升浏览体验。创新互联建站从事“诸城网站设计”,“诸城网站推广”以来,每个客户项目都认真落实执行。

socket编程中建立连接的两个进程都有一个socket来标识唯一一个连接。

网络字节序:网络数据流有大小端之分,发送主机通常将发送缓冲区中的数据按内存地址从低到高的顺序发出,接收主机把从网络上接到的字节依次保存在接收缓冲区中,也是按内存地址从低到高的顺序保存,网络数据流的地址规定:先发出的数据是低地址,后发出的数据是

地址。

TCP/IP协议规定,网络数据流应采用大端字节序,即低地址高字节。

例:如果端口号是1000(0x3e8),则地址0是0x03,地址1是0xe8, 也就是先发0x03,再发0xe8,这16位在发送主机的缓冲区中也应该是低地址存0x03,高地址存0xe8。但是,如果发送主机是小端字节序的,这16位端口号被解释成0xe803,不是1000。因此,发送主机把1000填到发送缓冲区之前需要做字节序的转换。同样地,接收主机如果是小端字节序的, 接到16位的源端口号也要做字节序的转换。如果主机是大端字节序的,发送和接收都不需要做转换。同理,32位的IP地址也要考虑网络字节序和主机字节序的问题。

服务器端socket:

1.创建套接字:int socket(int domain,int type,int protocol) //domain底层采用何种协议,传输类型,TCP面向字节流式

2.使用struct socketaddr_in 结构体填充网络方面信息

3.绑定:将套接字信息填充到内核中

4.设置套接字状态为监听状态,接收客户端发来的连接请求

5.等待客户请求,当请求连接来后,接受连接请求,返回一个新的对应于此次连接的套接字(accept)

6.新的套接字和客户端进行通信

accept函数:在一个套接口接受一个连接。

int accept(int sockfd,struct sockaddr*addr,socklen_t* addrlen)

 sockfd和 listen() 中套接字描述符相同。addr要求接入的信息所要去的地方。返回值:如果执行成功,返回值为0,否则设置错误码,返回-1。

bind函数:将一本地地址与一套接口捆绑。

int bind(int sockfd, const struct sockaddr* addr, socklen_t len);

适用于未连接的数据报或流类套接口,在connect()或listen()调用前使用。当用socket()创建套接口后,它便存在于一个名字空间(地址族)中,但并未赋名。bind()函数通过给一个未命名套接口分配一个本地名字来为套接口建立本地捆绑(主机地址/端口号)。

服务器端代码:

 1 #include
  2 #include
  3 #include
  4 #include
  5 #include
  6 #include
  7 #include
  8 #include
  9 int start(int _port,char* ip)
 10 {   
 11     //1.create sock
 12     int listen_sock=socket(AF_INET,SOCK_STREAM,0);
 13     if(listen_sock < 0){
 14         perror("sock");
 15         exit(1);
 16     }
 17     //2.fill information 
 18     struct sockaddr_in local;
 19     local.sin_family=AF_INET;
 20     local.sin_port=htons(_port);
 21     local.sin_addr.s_addr=inet_addr(ip);
 22     //3.bind
 23     if(bind(listen_sock,(struct sockaddr*)&local,sizeof(local))<0)
 24     {
 25         perror("bind");
 26         exit(2);
 27     }
 28     //4.set listen 
 29     if(listen(listen_sock,5)<0)
 30     {
 31         perror("listen");
 32         exit(3);
 33     }
 34     return listen_sock;
 35 
 36    
 37 }
 38 void usage(const char *proc)
 39 {   
 40     printf("usage:%s [ip] [port]\n",proc);
 41 }
 42 
 43 void* thread_run(void* arg)
 44 {
 45     int sock =(int)arg;
 46     char buf[1024];
 47     while(1)
 48     {
 49         memset(buf,'\0',sizeof(buf));
 50         ssize_t _size=read(sock,buf,sizeof(buf)-1);
 51         if(_size<0)
 52         {
 53             printf("read fail...\n");
 54             exit(1);
 55         }else if(_size==0)
 56         {
 57             printf("closed connect...\n");
 58             exit(2);
 59         }else
 60         {
 61             printf("client# %s\n",buf);
 62         }
 63     }
 64 }
 65 
 66 int main(int argc,char* argv[])
 67 {
 68     if(argc!=3)
 69     {
 70         usage(argv[0]);
 71         exit(1);
 72     }
 73     int listen_sock=start(atoi(argv[2]),argv[1]);
 74     struct sockaddr_in client;
 75     socklen_t len=sizeof(client);
 76     int done=0;
 77     while(!done)
 78     {
 79         int new_sock=accept(listen_sock,(struct sockaddr*)&client,&len);
 80         if(new_sock<0)
 81         {
 82             perror("accept");
 83             continue;
 84         }
 85         printf("get a connect... [sock]:%d [ip]:%s [port]:%d\n",new_sock,inet_ntoa(cl ient.sin_addr),ntohs(client.sin_port));
 86    
 87 #ifdef _V1_
 88         while(1)
 89         {
  90             char buf[1024];
 91             memset(buf,'\0',sizeof(buf));
 92             ssize_t _size=read(new_sock,buf,sizeof(buf)-1);
 93             if(_size<0)
 94             {
 95                 printf("read fail...\n");
 96                 exit(1);
 97             }else if(_size==0)
 98             {
 99                 printf("closed connect...\n");
100                 exit(2);
101             }else
102             {
103                 printf("client# %s",buf);
104             }
105         }
106     }
107 #elif _V2_
108         pid_t id=fork();
109         if(id<0)
110         {
111             printf("create fail...\n");
112             exit(3);
113         }else if(id==0)
114         {
115             close(listen_sock);//close listen_sock,only deal with I/Ostream
116             while(1)
117             {
118                 char buf[1024];
119                 memset(buf,'\0',sizeof(buf));
120                 ssize_t _size=read(new_sock,buf,sizeof(buf)-1);
121                 if(_size<0)
121                 if(_size<0)
122                 {
123                     printf("read fail...\n");
124                     exit(1);
125                 }else if(_size==0)
126                 {
127                     printf("closed connect...\n");
128                     exit(2);
129                 }else
130                 {
131                     printf("client# %s\n",buf);
132                 }
133             }
134             close(new_sock);
135         }else
136         {
137             close(new_sock);
138         }
139     }
140 
141 #elif _V3_
142         pthread_t tid;
143         if(tid=pthread_create(&tid,NULL,thread_run,(void*) new_sock)<0)
144         {
145             perror("pthread_create");
146             exit(2);
147         }
148         pthread_detach(tid);
149     }
150 #else
151     printf("default\n");
152     }
153 #endif 
154    return 0;
155 }

connect函数:

int connect(int sockfd, const struct sockaddr *addr,socklen_t addrlen);

向服务器端发送连接请求,只维护一个连接,连接成功后通过sock进行传输
客户端:

1.创建套接字(进行三次握手)

2.向服务器发连接请求

3.传输数据

4.关闭套接字(四次挥手,即释放链接)

客户端代码:

 1 #include
  2 #include
  3 #include
  4 #include
  5 #include
  6 #include
  7 #include
  8 
  9 void usage(char* proc)
 10 {
 11     printf("usage:%s [remoteip] [remoteport]\n",proc);
 12 }
 13 int main(int argc,char*argv[])
 14 {
 15     if(argc!=3)
 16     {
 17         usage(argv[0]);
 18         exit(1);
 19     }
 20     char* remote_ip=argv[1];
 21     int remote_port=atoi(argv[2]);
 22     int sock=socket(AF_INET,SOCK_STREAM,0);
 23     if(sock < 0)
 24     {
 25         perror("socket");
 26         exit(2);
 27     }
 28     struct sockaddr_in remote;
 29     remote.sin_family=AF_INET;
 30     remote.sin_port=htons(remote_port);
 31     remote.sin_addr.s_addr=inet_addr(remote_ip);
 32     //send SYN head
 33     if(connect(sock,(struct sockaddr*)&remote,sizeof(remote))<0)
 34     {
 35         perror("connect");
 36         exit(3);
 37     }
 38     char msg[1024];
 39     while(1)
 40     {
 41         memset(msg,'\0',sizeof(msg));
 42         printf("please input msg:");
 43         fflush(stdout);
 44         if(read(0,msg,sizeof(msg))>0){
 45             write(sock,msg,strlen(msg));
 46         }
 47    
 48     }
 49     return 0;
 50 }

运行结果:

单用户:

TCP之socket编程

利用线程模拟多用户:

TCP之socket编程

另外有需要云服务器可以了解下创新互联scvps.cn,海内外云服务器15元起步,三天无理由+7*72小时售后在线,公司持有idc许可证,提供“云服务器、裸金属服务器、高防服务器、香港服务器、美国服务器、虚拟主机、免备案服务器”等云主机租用服务以及企业上云的综合解决方案,具有“安全稳定、简单易用、服务可用性高、性价比高”等特点与优势,专为企业上云打造定制,能够满足用户丰富、多元化的应用场景需求。


当前文章:TCP之socket编程-创新互联
链接URL:http://cdkjz.cn/article/dsjidi.html
多年建站经验

多一份参考,总有益处

联系快上网,免费获得专属《策划方案》及报价

咨询相关问题或预约面谈,可以通过以下方式与我们联系

大客户专线   成都:13518219792   座机:028-86922220