linux網絡編程之socket(TCP)

對於網絡編程,有一種說法就是一切皆socket。

之前只是大概瞭解socket網絡編程的流程,最近學習了一下如何進行socket網絡編程,實現TCP通信。

下面是服務器端的例子:

/*socket網絡編程學習
服務器端:一直監聽本機的8000端口,如果收到連接請求,將接收請求並接受客戶端發來的信息,並向客戶端返回消息。
這個程序實現的是TCP併發服務器。
併發服務器的思想是每一個客戶機的請求並不由服務器直接處理,而是由服務器創建一個子進程來處理。
2016-4-5
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>

#define MAXLINE 4096
#define DEFAULT_PORT 8000

int main()
{
	int socket_fd,connect_fd;
	struct sockaddr_in  servaddr;	//用於記錄網絡地址
	char buff[4096];
	int n;
	//初始化
	memset(&servaddr ,0 ,sizeof(servaddr));		//結構體置零
	servaddr.sin_family=AF_INET;		//AF_INET表示IP協議族
	servaddr.sin_addr.s_addr=htonl(INADDR_ANY);		//IP地址設置爲INADDR_ANY,讓系統自動獲取本機的IP地址。
	servaddr.sin_port = htons(DEFAULT_PORT);		//設置的端口爲DEFAULT_PORT
	
	//初始化socket
	if((socket_fd = socket(AF_INET,SOCK_STREAM,0)) == -1)
	{
		printf("create socket error : %s(error: %d)\n",strerror(errno),errno);
		exit(0);
	}
	
	//將本地地址和端口號綁定到所創建的套接字上
	if(bind(socket_fd,(struct sockaddr*)&servaddr,sizeof(servaddr))==-1)		//可以將sockaddr換爲sockaddr_in,編譯會有警告
	{
		printf("bind socket error:%s(error:%d)\n",strerror(errno),errno);
		exit(0);
	}
	//開始監聽是否有客戶端連接,,,,並設置允許的最大連接數
	if(listen(socket_fd,10)==-1)
	{
		printf("listen socket error:%s(errno:%d)\n",strerror(errno),errno);
		exit(0);
	}
	printf("=====waiting for client's request ======\n");
	while(1)
	{
		//阻塞直到有客戶端連接,不然多浪費CPU資源。
		if((connect_fd=accept(socket_fd,(struct sockaddr*)NULL,NULL)) == -1)		//accept函數用來等待來自客戶端的socket的連接請求
		{
			printf("accept socket error :%s(errno:%d)\n",strerror(errno),errno);
			continue;
		}
		//接收客戶端傳過來的數據
		n=recv(connect_fd,buff,MAXLINE,0);
		//向客戶端發送迴應數據
		if(!fork())
		{
			if(send(connect_fd,"\tHello,your message has been received!\n",40,0)==-1)
				perror("send error");
			close(connect_fd);
			exit(0);		//關掉髮送進程
		}
		buff[n]='\0';
		printf("recv msg from client:\n\t%s",buff);
		close(connect_fd);
	}
	close(socket_fd);
}
接着是客戶端的代碼:

/*socket網絡編程學習		基於TCP網絡程序設計
客戶端:向相應的IP地址主機的8000端口發送數據,並接收回執。
2016-4-5
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>

#define DEFAULT_PORT 8000
#define MAXLINE 4096

int main(int argc,char **argv)
{
	int sockfd,n,rec_len;
	char recvline[4096],sendline[4096];
	char buf[MAXLINE];
	struct sockaddr_in servaddr;
	
	if(argc != 2)
	{
		printf("please input: ./client <ipaddress>\n");
		exit(0);
	}
	memset(&servaddr,0,sizeof(servaddr));
	servaddr.sin_family = AF_INET;
	servaddr.sin_port = htons(DEFAULT_PORT);
	if(inet_pton(AF_INET,argv[1],&servaddr.sin_addr)<=0)		//inet_pton是Linux下IP地址轉換函數,可以將IP地址在“點分十進制”和整數之間轉換。
	{
		printf("IP error:%s(errno:%d)\n",strerror(errno),errno);
		exit(0);
	}
	
	if((sockfd =socket(AF_INET,SOCK_STREAM,0))<0)		//創建一個socket
	{
		printf("create socket error :%s(errno:%d)\n",strerror(errno),errno);
		exit(0);
	}
	
	if(connect(sockfd,(struct sockaddr*)&servaddr,sizeof(servaddr))<0)		//連接服務器
	{
		printf("connect error :%s(errno:%d)\n",strerror(errno),errno);
		exit(0);
	}
	printf("send msg to server:\n");
	fgets(sendline,4096,stdin);
	if( send(sockfd,sendline,strlen(sendline),0)<0)			//發送數據
	{
		printf("send msg error :%s(errno:%d)\n",strerror(errno),errno);
		exit(0);
	}
	if((rec_len=recv(sockfd,buf,MAXLINE,0))==-1)		//接收回執
	{
		perror("recv error");
		exit(1);
	}
	buf[rec_len]='\0';
	printf("send success:%s",buf);		//打印回執
	close(sockfd);
	exit(0);
}

將兩個程序進行編譯運行。


接着運行着兩個程序:

客戶端發送CSDN給服務器,並接收來自服務器的回執。


服務器端收到來自客戶端發送的數據。



內容多參考:http://blog.csdn.net/hguisu/article/details/7445768/

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章