千家信息网

TCP之socket编程

发表于:2026-10-31 作者:千家信息网编辑
千家信息网最后更新 2026年10月31日,socket(套接字):IP地址+端口号,唯一标识网络中的一个进程socket编程中建立连接的两个进程都有一个socket来标识唯一一个连接。网络字节序:网络数据流有大小端之分,发送主机通常将发送缓冲
千家信息网最后更新 2026年10月31日TCP之socket编程

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

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             }else102             {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/Ostream116             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                 }else130                 {131                     printf("client# %s\n",buf);132                 }133             }134             close(new_sock);135         }else136         {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 #else151     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 }


运行结果:

单用户:



利用线程模拟多用户:



地址 字节 主机 套接字 数据 网络 口号 客户 函数 客户端 服务器 缓冲区 服务 缓冲 信息 数据流 传输 成功 代码 内存 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 南京欣网互联网络科技有限公司 中国互联网科技工作委员会毛军 深圳恒合互联网络科技有限公司 互联网科技保险 智能科技公司是互联网公司吗 广州互联网科技公司 狮子座互联网科技 宜安科技 互联网金融 顺玮阁互联网科技 深圳市运趣互联网科技有限公司 中国科技互联网公司收入 常德市电业局互联网科技部 贵州叶脉互联网科技有限公司所属行业 宁夏科技产业互联网案例 花神(南京)互联网科技有限公司 朱啸虎曾投资哪些互联网科技企业 互联网科技大赛获奖感言 福仕德教育科技互联网 悟空问答互联网科技 互联网科技大佬云集 科技制造互联网公司 深圳互联网科技公司 互联网的科技创新 天津摩尔互联网科技 腾讯科技 互联网女皇 剑昆互联网络科技有限公司临桂 千方科技属于互联网企业吗 互联网科技大奖都有哪些公司 中天科技中国工业互联网 互联网科技快讯热点
0