日期:2014-05-16  浏览次数:20573 次

循序渐进学unix——上机记录(七),socket

本次的主题是基本网络编程:socket,涉及到的概念比较多,就不详细展开了。从编程角度简单的说,为了在客户端和服务器之间建立一个连接,服务器端需要依次调用这些函数:

  1. socket,获得一个socket
  2. bind,将获得的socket绑定到指定的地址和端口
  3. listen,让此socket进入等待状态,等待客户端的连接
  4. accept,当建立起与客户端之间的连接时,此函数返回代表此连接的socket。即类似于文件描述符,我们可以把客户端看作文件,向网络上进行读写操作,从而完成通信过程。
客户端需要调用的函数:
  1. socket
  2. connect,向指定地址的服务器的指定端口发起连接
服务器和客户端都需用到的通信函数:
  1. send
  2. recv
详细信息和函数方法等就不赘述了,请参见man 文档。

下面来看几道练习。
1. 从客户端把用户输入的信息发送到服务器,直到用户输入“over”。这是一道基础题,直接上代码了。
server:
#include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>

int main(int argc, char *argv[])
{
	int numPort, lenMsg, i;
	int sockServ, sockClient;
	struct sockaddr_in adrServ, adrClient;
	char message[256];
	char * overMsg = "over";
	int adrSize = sizeof(adrClient);
	int yes = 1;

	if(argc < 2)
	{
		printf("syntaxe : %s numPort\n", argv[0]);
		return -1;
	}
	

	//set local addr and port
	numPort = atoi(argv[1]);
	adrServ.sin_addr.s_addr = INADDR_ANY;
	adrServ.sin_family = AF_INET;
	adrServ.sin_port = htons(numPort);
	bzero(&(adrServ.sin_zero), 8) ;
	
	//Get a socket
	if((sockServ = socket(PF_INET, SOCK_STREAM, 0)) == -1) { perror("sockServet"); return -1; }
	
	//We can set some param here.// paramètrage de la socket pour réutiliser le N° ce port sans délai
	if(setsockopt(sockServ, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1) { perror("setsockopt"); return -1; }

	// bind
	if(bind(sockServ, (struct sockaddr *)(&adrServ), sizeof(adrServ)) == -1) { perror("bind"); return -1; }

	// place la socket en écoute
	if(listen(sockServ, 1) == -1) { perror("listen"); return -1; }
	

	// wait for a connection from a client
	if((sockClient = accept(sockServ, (struct sockaddr *)(&adrClient), &adrSize)) == -1) { perror("accept"); return -1; }
	printf("New socket client : %s\n", inet_ntoa(adrClient.sin_addr));
	do
	{
		// Read a msg from client
		if((lenMsg = recv(sockClient, message, 256, 0)) == -1)
		{ perror("recv"); return -1; }
		message[lenMsg] = '\0';
		printf("New msg received : %s\n", message);
		//printf("New msg received : %s, %d\n", message, strcmp(message, overMsg));
		
	}while(strcmp(message, overMsg) != 0);	
	// fermeture de la connexion
	close(sockServ);
	
	return 0;
}


client:
#include<stdio.h>
#include<stdlib.h>
#include<netinet/in.h>
#include<sys/types.h>
#include<unistd.h>
#include<sys/socket.h>
#include<string.h>
void main(int argc, char* argv[])
{
	if(argc < 3)
	{
		printf("Syntax:%s server_addr <portNum>\n", argv[0]);
		exit(0);
	}


	int fdSock;
	//get a socket
	if( (fdSock=socket(AF_INET, SOCK_STREAM, 0)) == -1){perror("socket"); exit(1);}
	
	//config the address of the server to connect
	struct sockad