Socket编程

Socket编程很简单。因为不管用什么语言、什么环境编写,都是那几个固定的步骤。

Socket可以通过TCP\IP和UDP两种方式实现。

TCP\IP

  tcp建立连接要进行“三次握手”,即交换三个分组。大致流程如下:

  • 客户端向服务器发送一个SYN J
  • 服务器向客户端响应一个SYN K,并对SYN J进行确认ACK J+1
  • 客户端再想服务器发一个确认ACK K+1

  当客户端调用connect时,触发了连接请求,向服务器发送了SYN J包,这时connect进入阻塞状态;服务器监听到连接请求,即收到SYN J包,调用accept函数接收请求向客户端发送SYN K ,ACK J+1,这时accept进入阻塞状态;客户端收到服务器的SYN K ,ACK J+1之后,这时connect返回,并对SYN K进行确认;服务器收到ACK K+1时,accept返回,至此三次握手完毕,连接建立。

Linux下实现,看下面的例子。windows下微软已经封装很好了,更简单一些,这里不赘述。

一、Server端。

View Code
#include <stdlib.h>
#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <fcntl.h>
#include <string.h>


int open_file(const char* filename)
{
        int fd;

        if ((fd = open(filename, O_CREAT | O_RDWR, 0666)) < 0) {
                printf("open error");
		return 0;
        }
        else {
        //        printf("Open file%d\n", fd);
        }

        return fd;
}

void write_file(int fd, char *buf, int len)
{
	lseek(fd, 0, SEEK_END);
        if (write(fd, buf, len) < 0) {
                printf("write error");
        }
        else {
        //        printf("Write: %s\n", buf);
        }
}

void read_file(int fd, int len)
{
        char buff[len + 1];

        lseek(fd, 0, SEEK_SET);
        if (read(fd, buff, len) < 0) {
                printf("read error");
        }
        else {
                buff[len] = '\0';
          //      printf("read from file: %s\n", buff);
        }
}

void close_file(int fd)
{
        if (close(fd) < 0) {
                printf("close error");
        }
        else 
	{//do nothing, close file right
        }
}

int main(int argc, char *argv[])
{
    // Get Port option
    if (argc < 2)
    {
        fprintf(stderr, "ERROR, no port provided\n");
        exit(1);
    }
    int port_no = atoi(argv[1]);

    // Get socket
    int socket_fd = socket(AF_INET, SOCK_STREAM, 0);

    // Bind
    struct sockaddr_in server_addr;
    bzero((char *) &server_addr, sizeof(server_addr));
    server_addr.sin_family = AF_INET;
    server_addr.sin_addr.s_addr = INADDR_ANY;
    server_addr.sin_port = htons(port_no);
    bind(socket_fd, (struct sockaddr *) &server_addr, sizeof(server_addr));

    // Listen
    listen(socket_fd, 5);

    while (1) {

        // Accept
        struct sockaddr_in client_addr;
        socklen_t client_addr_length = sizeof(client_addr);
        int socket_to_client = accept(socket_fd, (struct sockaddr *) &client_addr, &client_addr_length);

        // Read the buffer from the socket
        char buffer[1024*10240];
        bzero(buffer, sizeof(buffer));
        read(socket_to_client, buffer, sizeof(buffer) - 1);
    //上面这个函数可以用下面的这个代替
    //recv(socket_toclient, buffer, sizeof(buffer)-1, 0);
//printf("Here is the message: %s\n", buffer); //write the string into the file int fd = open_file("server.log"); if(fd > 0) { int len = strlen(buffer); write_file(fd, buffer, len); close_file(fd); } // Write const char *data = "I got your message."; write(socket_to_client, data, strlen(data)); // Close close(socket_to_client); } close(socket_fd); return 0; }

  

二、Client端。

View Code
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdio.h>
#include <string.h>
#include <netdb.h> // bcopy
#include <stdlib.h>

int main(int argc, char *argv[])
{
  // Get options
  if (argc < 3)
  {
    fprintf(stderr, "Usage: %s <hostname> <port>\n", argv[0]);
    exit(1);
  }
  struct hostent *server_host = gethostbyname(argv[1]);
  int server_port = atoi(argv[2]);

  // Get socket
  int socket_fd = socket(AF_INET, SOCK_STREAM, 0);

  // Connect
  struct sockaddr_in server_addr;
  bzero((char *) &server_addr, sizeof(server_addr));
  server_addr.sin_family = AF_INET;
  bcopy((char *) server_host->h_addr, (char *) &server_addr.sin_addr.s_addr, server_host->h_length);
  server_addr.sin_port = htons(server_port);
  connect(socket_fd, (struct sockaddr *) &server_addr, sizeof(server_addr));

  // Input
  printf("Please enter the message: ");
  char buffer[1024];
  bzero(buffer, sizeof(buffer));
  fgets(buffer, sizeof(buffer) - 1, stdin);

  // Write
  write(socket_fd, buffer, strlen(buffer));

  // Read
  bzero(buffer, sizeof(buffer));
  read(socket_fd, buffer, sizeof(buffer) - 1);
  printf("%s\n", buffer);

  // Close
  close(socket_fd);

  return 0;
}


 1 #include <sys/socket.h>
2 #include <netinet/in.h>
3 #include <stdio.h>
4 #include <string.h>
5 #include <netdb.h> // bcopy
6 #include <stdlib.h>
7
8 int main(int argc, char *argv[])
9 {
10 // Get options
11 if (argc < 3)
12 {
13 fprintf(stderr, "Usage: %s <hostname> <port>\n", argv[0]);
14 exit(1);
15 }
16 struct hostent *server_host = gethostbyname(argv[1]);
17 int server_port = atoi(argv[2]);
18
19 // Get socket
20 int socket_fd = socket(AF_INET, SOCK_STREAM, 0);
21
22 // Connect
23 struct sockaddr_in server_addr;
24 bzero((char *) &server_addr, sizeof(server_addr));
25 server_addr.sin_family = AF_INET;
26 bcopy((char *) server_host->h_addr, (char *) &server_addr.sin_addr.s_addr, server_host->h_length);
27 server_addr.sin_port = htons(server_port);
28 connect(socket_fd, (struct sockaddr *) &server_addr, sizeof(server_addr));
29
30 // Input
31 printf("Please enter the message: ");
32 char buffer[1024];
33 bzero(buffer, sizeof(buffer));
34 fgets(buffer, sizeof(buffer) - 1, stdin);
35
36 // Write
37 write(socket_fd, buffer, strlen(buffer));
38
39 // Read
40 bzero(buffer, sizeof(buffer));
41 read(socket_fd, buffer, sizeof(buffer) - 1);
42 printf("%s\n", buffer);
43
44 // Close
45 close(socket_fd);
46
47 return 0;
48 }

UDP

看例子代码。

Server端。

View Code

Client端。

View Code
 1 #include <sys/socket.h>
2 #include <string.h>
3 #include <netinet/in.h>
4 #include <netdb.h>
5
6 int main(int argc, char *argv[])
7 {
8 // Create socket
9 int socket_fd = socket(AF_INET, SOCK_DGRAM, 0);
10
11 // Initialize server address
12 struct hostent *server_host = gethostbyname(argv[1]);
13 struct sockaddr_in server_addr;
14 server_addr.sin_family = AF_INET; // socket internet family
15 bcopy((char *)server_host->h_addr, (char *)&server_addr.sin_addr.s_addr, server_host->h_length); // socket internet address
16 server_addr.sin_port = htons(atoi(argv[2])); // socket internet port
17
18 // Send
19 char buffer[1024];
20 sendto(socket_fd, buffer, sizeof(buffer), 0, (const struct sockaddr *) &server_addr, sizeof(struct sockaddr_in));
21
22 // Receive and write
23 struct sockaddr_in client_addr;
24 socklen_t client_addr_length = sizeof(client_addr);
25 int msg_recv_length = recvfrom(socket_fd, buffer, sizeof(buffer), 0, (struct sockaddr *) &client_addr, &client_addr_length);
26 const char *hint = "Got an ACK: ";
27 write(1, hint, strlen(hint));
28 write(1, buffer, msg_recv_length);
29
30 // Close
31 close(socket_fd);
32
33 return 0;
34 }



posted @ 2012-03-27 17:28  陈朋  阅读(453)  评论(0编辑  收藏  举报