Linux下C语言实现简单的套接字编程
文章最后更新时间为:2019年04月11日 14:27:27
一篇水水的文章,仅记录用。
0x01 服务端 tcp_server.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#define PORT 9999 /*侦听端口地址*/
#define BACKLOG 2 /*侦听队列长度*/
/*服务器对客户端的处理*/
void process_conn_server(int s)
{
ssize_t size = 0;
char buffer_recv[1024]; /*数据的缓冲区*/
char buffer_send[1024];
for(;;){ /*循环处理过程*/
size = read(s, buffer_recv, 1024); /*从套接字中读取数据放到缓冲区buffer中*/
if(size == 0){ /*没有数据*/
return;
}
/*构建响应字符,为接收到客户端字节的数量*/
sprintf(buffer_send, "%d bytes altogether:%s\n", size, buffer_recv);
write(s, buffer_send, strlen(buffer_send)+1);/*发给客户端*/
}
}
int main(int argc, char *argv[])
{
int ss,sc; /*ss为服务器的socket描述符,sc为客户端的socket描述符*/
struct sockaddr_in server_addr; /*服务器地址结构*/
struct sockaddr_in client_addr; /*客户端地址结构*/
int err; /*返回值*/
pid_t pid; /*分叉的进行ID*/
/*建立一个流式套接字*/
ss = socket(AF_INET, SOCK_STREAM, 0);
if(ss < 0){ /*出错*/
printf("socket error\n");
return -1;
}
/*设置服务器地址*/
bzero(&server_addr, sizeof(server_addr)); /*清零*/
server_addr.sin_family = AF_INET; /*协议族*/
server_addr.sin_addr.s_addr = htonl(INADDR_ANY); /*本地地址*/
server_addr.sin_port = htons(PORT); /*服务器端口*/
/*绑定地址结构到套接字描述符*/
err = bind(ss, (struct sockaddr*)&server_addr, sizeof(server_addr));
if(err < 0){/*出错*/
printf("bind error\n");
return -1;
}
/*设置侦听*/
err = listen(ss, BACKLOG);
if(err < 0){ /*出错*/
printf("listen error\n");
return -1;
}
/*主循环过程*/
for(;;) {
socklen_t addrlen = sizeof(struct sockaddr);
sc = accept(ss, (struct sockaddr*)&client_addr, &addrlen);
/*接收客户端连接*/
if(sc < 0){ /*出错*/
continue; /*结束本次循环*/
}
/*建立一个新的进程处理到来的连接*/
pid = fork(); /*分叉进程*/
if( pid == 0 ){ /*子进程中*/
process_conn_server(sc); /*处理连接*/
close(ss); /*在子进程中关闭服务器的侦听*/
}else{
close(sc); /*在父进程中关闭客户端的连接*/
}
}
}
0x02 客户端 tcp_client.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/stat.h>
#include <fcntl.h>
#define PORT 9999 /*侦听端口地址*/
/*客户端的处理过程*/
void process_conn_client(int s)
{
ssize_t size = 0;
char buffer[1024]; /*数据的缓冲区*/
for(;;){ /*循环处理过程*/
/*从标准输入中读取数据放到缓冲区buffer中*/
size = read(0, buffer, 1024);
if(size > 0){ /*读到数据*/
write(s, buffer, size); /*发送给服务器*/
size = read(s, buffer, 1024); /*从服务器读取数据*/
write(1, buffer, size); /*写到标准输出*/
}
}
}
int main(int argc, char *argv[])
{
int s; /*s为socket描述符*/
struct sockaddr_in server_addr; /*服务器地址结构*/
if(argc<2) {
printf("Usage ./client server-addr\n");
return 0;
}
s = socket(AF_INET, SOCK_STREAM, 0); /*建立一个流式套接字 */
if(s < 0){ /*出错*/
printf("socket error\n");
return -1;
}
/*设置服务器地址*/
bzero(&server_addr, sizeof(server_addr)); /*清零*/
server_addr.sin_family = AF_INET; /*协议族*/
server_addr.sin_addr.s_addr = htonl(INADDR_ANY); /*本地地址*/
server_addr.sin_port = htons(PORT); /*服务器端口*/
/*将用户输入的字符串类型的IP地址转为整型*/
inet_pton(AF_INET, argv[1], &server_addr.sin_addr);
/*连接服务器*/
connect(s, (struct sockaddr*)&server_addr, sizeof(struct sockaddr));
process_conn_client(s); /*客户端处理过程*/
close(s); /*关闭连接*/
return 0;
}
0x03 结果
编译一下:
gcc tcp_server.c -o server
gcc tcp_client.c -o client
运行结果: