【学习笔记】简单的socket网络编程实例

来源:互联网 发布:数据集中管理 编辑:程序博客网 时间:2024/06/03 20:04

TCP的三次握手(图片来自百度百科)


TCP的四次分手(图片来自百度百科)




单向交互套结字

服务端

描述符,sfp接收所有连接请求,然后将每个连接传给对应的一个nfp。类似电话总机与分机。

/* * Author:xusongqi@live.com* * Created Time: 2014年03月19日 星期三 17时29分14秒* * FileName:     sock_server.c* * Description:  **/#include <stdio.h>#include <stdlib.h>#include <sys/types.h>#include <linux/in.h>#include <string.h>#include <sys/socket.h>int main(void){int sfp,nfp;//两个描述符struct sockaddr_in server_addr,client_addr;//服务器地址,客户端地址int sin_size;//???unsigned short portnum = 0x8888;//服务器使用端口printf("Here's a socket server\n");sfp = socket(AF_INET, SOCK_STREAM,0);if(sfp == -1){printf("SOCKET FAILED\n");exit(1);}printf("SOCKET SUCCEED\n");/*设置监听的端口和IP信息*/bzero(&server_addr, sizeof(struct sockaddr_in));server_addr.sin_family=AF_INET;server_addr.sin_addr.s_addr=htonl(INADDR_ANY);server_addr.sin_port=htons(portnum);/*bind() 端口绑定函数*/if(-1 == bind(sfp,(struct sockaddr *)(&server_addr),sizeof(struct sockaddr))){printf("BIND FAILED\n");exit(1);}printf("BIND SUCCEED\n");/*listen 监听端口函数*/if(-1 == listen(sfp,5)){printf("LISTEN FAILED\n");exit(1);}printf("LISTEN SUCCEED\n");while(1){sin_size = sizeof(struct sockaddr_in);/*服务端accept函数,调用即进入阻塞状态,等待用户连接。 *在没有用户进行连接时,程序停在此处。 *此处accpet的第二个参数用于获取客户端的端口和地址信息。 */nfp = accept(sfp,(struct sockaddr *)(&client_addr),&sin_size);if(nfp == -1){printf("ACCEPT FAILED\n");exit(1);}printf("ACCEPT SUCCEED\nSERVER START GET CONNECT FROM %#x\n",ntohl(client_addr.sin_addr.s_addr),ntohs(client_addr.sin_port));/*函数向客户端使用write函数发送信息,也可以尝试使用其他函数实现*/if(-1 == write(nfp,"SOCKET CONNECTED,WELCOME!\n",30));{printf("WRITE FAILED\n");exit(1);}printf("WRITE SUCCEED\n");close(nfp);}close(sfp);return 0;}


客户端

/* * Author:xusongqi@live.com* * Created Time: 2014年03月20日 星期四 18时42分19秒* * FileName:     sock_client.c* * Description:  **/#include <stdio.h>#include <stdlib.h>#include <string.h>#include <linux/in.h>#include <sys/socket.h>#include <sys/types.h>#define LENGTH 1024int main(void){int cfd;//文件描述符int recbytes;int sin_size;char buffer[LENGTH]={0};//接受缓冲区struct sockaddr_in server_addr,client_addr;//服务器信息,客户端信息unsigned short portnum=0x8888;//服务端使用的通信端口,可更改,但必须与服务端保持一致printf("here's a socket client\n");//建立socket,使用tcp流传输cfd = socket(AF_INET,SOCK_STREAM,0);if(cfd == -1){printf("SOCKET FAILED\n");exit(1);}printf("SOCKET SUCCEED\n");//构造服务器端的ip及端口信息bzero(&server_addr,sizeof(struct sockaddr_in));server_addr.sin_family = AF_INET;server_addr.sin_addr.s_addr = inet_addr("127.0.0.1");//ip转换为4字节整型,使用时需要根据服务器端ip进行更改server_addr.sin_port = htons(portnum);//htons将short转化为网络型,即:将小端数据转化为大端数据(以两字节为单位,首尾交换)//一般来说网络为大端,PPC的cpu为大端,x86的cpu为小端,arm可以配置大小端、printf("server_addr = %#x, port: %#x\n",server_addr.sin_addr.s_addr,server_addr.sin_port);//打印出小端//客户端连接服务端,参数顺序为socket描述符,地址信息,地址结构大小if(-1 == connect(cfd,(struct sockaddr *)(&server_addr),sizeof(server_addr))){printf("CONNECT FAILED\n");exit(1);}printf("CONNECT SUCCEED\n");//连接成功,从服务器端接收字符if(-1 == (recbytes = read(cfd,buffer,LENGTH))){printf("READ FAILED\n");exit(1);}printf("READ SUCCEED\n");buffer[recbytes]='\0';printf("%s\n",buffer);//输入任意字符结束程序puts("press any key to end\n");getchar();close(cfd);//关闭连接return 0;}


双向自由交互套结字

服务端

/* * Author:xusongqi@live.com* * Created Time: 2014年03月121日 星期三 17时26分23秒* * FileName:     while_sock_server.c* * Description:  **/#include <stdio.h>#include <stdlib.h>#include <sys/types.h>#include <linux/in.h>#include <string.h>#include <sys/socket.h>#define LENGTH 1024int main(void){//write()相关变量int sfp,nfp;//两个描述符struct sockaddr_in server_addr,client_addr;//服务器地址,客户端地址int sin_size;//???unsigned short portnum = 8086;//服务器使用端口char server_msg[LENGTH];char sock_flush;//read()相关变量char buffer[LENGTH];//存储read()收到的信息int recbytes;//计数器,计算buffer收到的字节数printf("Here's a socket server\n");sfp = socket(AF_INET, SOCK_STREAM,0);if(sfp == -1){printf("SOCKET FAILED\n");exit(1);}printf("SOCKET SUCCESS\n");/*设置监听的端口和IP信息*/bzero(&server_addr, sizeof(struct sockaddr_in));server_addr.sin_family=AF_INET;server_addr.sin_addr.s_addr=htonl(INADDR_ANY);server_addr.sin_port=htons(portnum);/*bind() 端口绑定函数*/if(-1 == bind(sfp,(struct sockaddr *)(&server_addr),sizeof(struct sockaddr))){printf("BIND FAILED\n");exit(1);}printf("BIND SUCCESS\n");/*listen 监听端口函数*/if(-1 == listen(sfp,5)){printf("LISTEN FAILED\n");exit(1);}printf("LISTEN SUCCESS\n");sin_size = sizeof(struct sockaddr_in);/*服务端accept函数,调用即进入阻塞状态,等待用户连接。 *在没有用户进行连接时,程序停在此处。 *此处accpet的第二个参数用于获取客户端的端口和地址信息。 */nfp = accept(sfp,(struct sockaddr *)(&client_addr),&sin_size);if(nfp == -1){printf("ACCEPT FAILED\n");exit(1);}printf("ACCEPT SUCCESS\nSERVER START GET CONNECT FROM %#x\n",ntohl(client_addr.sin_addr.s_addr),ntohs(client_addr.sin_port));if(fork() == 0){/*函数向客户端使用write函数发送信息,也可以尝试使用其他函数实现*///尝试发送消息if(-1 == write(nfp,"SOCKET CONNECTED,WELCOME!\n",30)){printf("WRITE FAILED\n");exit(1);}printf("WRITE SUCCESS\n");//write() 发送消息while(1){gets(server_msg);if(-1 == write(nfp,server_msg,strlen(server_msg))){printf("WRITE FAILED\n");exit(1);}memset(server_msg,0,strlen(server_msg));//while(((sock_flush = getchar()) != '\n') && (sock_flush != EOF));//flush cacheprintf("    【SEND SUCCESS】\n");}close(nfp);}else{//read() 接收信息while(1){if( (recbytes = read(nfp,buffer,LENGTH)) <= 0){break;}buffer[recbytes]='\0';printf("%s\n",buffer);printf("    【READ SUCCESS】\n");}close(nfp);}close(sfp);return 0;}


客户端

/* * Author:xusongqi@live.com* * Created Time: 2014年03月21日 星期四 17时27分36秒* * FileName:     sock_client.c* * Description:  **/#include <stdio.h>#include <stdlib.h>#include <string.h>#include <linux/in.h>#include <sys/socket.h>#include <sys/types.h>#define LENGTH 1024int main(void){int cfd;//句柄,文件描述符int recbytes;//计数器,计算接收到的字节数int sin_size;char buffer[LENGTH]={0};//存储read()收到的数据char client_msg[LENGTH];//存储write()发送的数据struct sockaddr_in server_addr,client_addr;//服务器信息,客户端信息unsigned short portnum=8086;//服务端使用的通信端口,可更改,但必须与服务端保持一致printf("here's a socket client\n");//建立socket,使用tcp流传输cfd = socket(AF_INET,SOCK_STREAM,0);if(cfd == -1){printf("SOCKET FAILED\n");exit(1);}printf("SOCKET SUCCESS\n");//构造服务器端的ip及端口信息bzero(&server_addr,sizeof(struct sockaddr_in));server_addr.sin_family = AF_INET;server_addr.sin_addr.s_addr = inet_addr("127.0.0.1");//ip转换为4字节整型,使用时需要根据服务器端ip进行更改server_addr.sin_port = htons(portnum);//htons将short转化为网络型,即:将小端数据转化为大端数据(以两字节为单位,首尾交换)//一般来说网络为大端,PPC的cpu为大端,x86的cpu为小端,arm可以配置大小端、printf("server_addr = %#x, port: %#x\n",server_addr.sin_addr.s_addr,server_addr.sin_port);//打印出小端//connect连接函数,客户端连接服务端,参数顺序为socket描述符,地址信息,地址结构大小if(-1 == connect(cfd,(struct sockaddr *)(&server_addr),sizeof(server_addr))){printf("CONNECT FAILED\n");exit(1);}printf("CONNECT SUCCESS\n");//分裂进程,分别进行读read()和写write()if(fork() == 0){//while(strcmp(buffer, "end")!=0)while(1){if((recbytes = read(cfd,buffer,LENGTH)) <= 0){//break;exit(0);}buffer[recbytes]='\0';printf("%s\n",buffer);printf("    【READ SUCCESS】\n");}close(cfd);//关闭连接}else{//write() 发送消息while(1){gets(client_msg);if(-1 == write(cfd,client_msg,strlen(client_msg))){printf("WRITE FAILED\n");exit(1);}memset(client_msg,0,strlen(client_msg));//while(((sock_flush = getchar()) != '\n') && (sock_flush != EOF));//flush cacheprintf("    【SEND SUCCESS】\n");}close(cfd);}close(cfd);//同步关闭read()与write()return 0;}


参考资料

linux下C语言socket网络编程简例

sockaddr_in结构体构成_百度知道

《linux c编程实战》童永清

0 0
原创粉丝点击