现在的位置: 首页 > 综合 > 正文

Linux中的TCP通信

2019年10月16日 ⁄ 综合 ⁄ 共 1925字 ⁄ 字号 评论关闭

客户端:

#include "apue.h"
#include <netdb.h>
#include <sys/socket.h>
#include <fcntl.h>

int main(void){
	int c_fd;
	struct sockaddr_in s_addr;	/*linux套接字地址需转化成通用sockaddr结构地址*/
	char buf[MAXLINE] = "hello server!\n";

	/* (1) 建立套接字 */
	if((c_fd = socket(AF_INET,SOCK_STREAM,0)) < 0)
		printf("socket error\n");

	//初始化服务器端地址
	s_addr.sin_family = AF_INET;
	inet_pton(AF_INET,"127.0.0.1",(void *)&s_addr.sin_addr.s_addr,INET_ADDRSTRLEN);
	s_addr.sin_port = htons(5000);
	
	/* (2) 请求连接服务器(在通信套接字上) */
	if(connect(c_fd,(struct sockaddr *)&s_addr,sizeof(s_addr)) < 0)
		printf("connect error\n");

	/* (3) 在该套接字上发送(接收)数据 */
	if(send(c_fd,"hello server",MAXLINE,0) < 0) 
		printf("send error\n");
	if(recv(c_fd,buf,MAXLINE,0) < 0) 
		printf("reccv error\n");
	printf("server send: %s\n",buf);

	/* (4) 关闭套接字 */
	close(c_fd);

	exit(0);
}

服务器端:

#include "apue.h"
#include <netdb.h>
#include <sys/socket.h>

int main(void){
	int reuse = 1;
	struct sockaddr_in s_addr;/*linux套接字地址需转化成通用sockaddr结构地址*/
	int r_fd,s_fd;
	char buf[MAXLINE];

	/* (1)建立STREAM套接字 */
	if((r_fd = socket(AF_INET,SOCK_STREAM,0)) < 0)
		printf("socket error\n");

	/*
		注意:当客户端正在和服务器端通信,此时客户端在等待接收服务器端消息。
		但是服务器却退出了,尝试重启,但是根本无法重启,而是会显示“bind error”。
		这是由于该地址(IP+端口号)已经被绑定到一个套接字的原因。
		TCP不允许重复绑定一个地址,除非超时以后这个地址才能重新被绑定。
		---但是可以使用setsocketopt()函数设置套接字选项,使得当前与该套接字
		绑定的地址可以被重复绑定 !!!
	*/
	setsockopt(r_fd,SOL_SOCKET,SO_REUSEADDR,&reuse,sizeof(int));

	/* (2)绑定用于接收请求的套接字和服务器地址 */
	s_addr.sin_family = AF_INET;
	s_addr.sin_addr.s_addr = htonl(INADDR_ANY);
	s_addr.sin_port = htons(5000);
	if(bind(r_fd,(struct sockaddr *)&s_addr,sizeof(s_addr)) < 0)
		printf("bind error\n");
	
	/* (3)宣告服务器通信端可以接受连接请求 */
	if(listen(r_fd,5) < 0) printf("listen error\n");

	/* (4)等待客户连接:若accept()返回,则建立连接,返回一个新套接字(用于通信) */
	for(;;){
		printf("waiting for ask...\n");
		fflush(stdout);
		//不关心客户端sockaddr地址
		s_fd = accept(r_fd,NULL,NULL);

		/* (5)在该套接字上面读写(处理请求) */
		if(recv(s_fd,buf,MAXLINE,0) < 0)
			printf("recv error\n");
		if(send(s_fd,"OK,I have recevied your quest\n",MAXLINE,0) < 0)
			printf("send error\n");
		if(send(s_fd,"O",1,MSG_OOB) < 0)
			printf("send error\n");
		printf("client send: %s\n",buf);
	}
	/* (6)关闭新套接字和原始套接字 */
	close(r_fd);
	close(s_fd);

	exit(0);
}

抱歉!评论已关闭.