Socket Programming Lecture 2

advertisement
Sop, Fan
07302010028@fudan.edu.cn
Reference: Daniel Spangenberger
Computer Networks
PPT-4 Socket Programming

Concurrency Review
 Why should we use …?
 Our experiences?

Socket Programming related
 System requirement(robustness…)
 How to cooperate with socket API?

Example
 How to modify the example to fit further requirement?
Clients
User 1
Server
connect()
accept()
fgets()
(goes to lunch)
Blocks!
read()
User 2
connect()
Blocked!

Processes
 Uses fork()
 Easy to understand(actually we have implemented one version!)
 A lot to consider about causing complexity(zombie, syscall…)

Threads
 Natural concurrency (new thread per connection)
 Easier to understand (you know it already)
 Complexity is increased (possible race conditions)

Use non-blocking I/O
 Uses select()
 Explicit control flow (no race conditions!)
 Explicit control flow more complicated though

Fork()
 Use Pid to verify different process
 Assign different task flow accordingly

Signal & waitpid(…)
 Tracing child processes, kill the zombies

Other process control methods?

pthread_create
 Create thread according to detailed settings

Pthread(series: join, detach, cancel…)
 Imply different polices.

Other thread control methods?

Monitor sockets with select()
 int select(int maxfd, fd_set *readfds, fd_set
*writefds, fd_set *exceptfds, const
struct timespec *timeout);

So what’s an fd_set?
 Bit vector with FD_SETSIZE bits
maxfd – Max file descriptor + 1
 readfs – Bit vector of read descriptors to monitor
 writefds – Bit vector of write descriptors to monitor
 exceptfds – Read the manpage, set to NULL
 timeout – How long to wait with no activity before
returning, NULL for eternity


void FD_ZERO(fd_set *fdset);
 Clears all the bits

void FD_SET(int fd, fd_set *fdset);
 Sets the bit for fd

void FD_CLR(int fd, fd_set *fdset);
 Clears the bit for fd

int FD_ISSET(int fd, fd_set *fdset);
 Checks whether fd’s bit is set

Requirements
 Mass users
 User Experience

Incidents
 Server/Network/Client breakdown?
 Hacking?
 …
Client(s)
socket()
Server
socket()
bind()
listen()
select()
connect()
FD_ISSET(sfd)
accept()
Hacking! Hacking!!!
write()
read()
Server breakdown!
read()
write()
Exceptions here!
close()
check_clients() main loop
read()
close()
…
Socket API offers variable settings to meet different
demands. (methods settings)

Programming concurrency with different detailed
settings .


Exception/ error cases handling

Address re-use
int sock, opts;
sock = socket(…);
// getting the current options
setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &opts, sizeof(opts));

Non-blocking
// getting current options
if (0 > (opts = fcntl(sock, F_GETFL)))
printf(“Error…\n”);
// modifying and applying
opts = (opts | O_NONBLOCK);
if (fcntl(sock, F_SETFL, opts))
printf(“Error…\n”);
bind(…);

An easy model.
struct sockaddr_in saddr, caddr;
int sockfd, clen, isock;
unsigned short port = 80;
if (0 > (sockfd=socket(AF_INET, SOCK_STREAM, 0)))
printf(“Error creating socket\n”);
memset(&saddr, '\0', sizeof(saddr));
saddr.sin_family = AF_INET;
saddr.sin_addr.s_addr = htonl(INADDR_ANY);
saddr.sin_port = htons(port);
if (0 > (bind(sockfd, (struct sockaddr *) &saddr,
sizeof(saddr)))
printf(“Error binding\n”);
if (listen(sockfd, 5) < 0) { // listen for incoming
connections
printf(“Error listening\n”);
clen = sizeof(caddr)
// Setup your read_set with FD_ZERO and the server socket
descriptor
while (1) {
pool.ready_set = &pool.read_set;
pool.nready = select(pool.maxfd+1, &pool.ready_set,
&pool.write_set, NULL, NULL);
if (FD_ISSET(sockfd, &pool.ready_set)) {
if (0 > (isock = accept(sockfd, (struct sockaddr
*)
&caddr, &clen)))
printf(“Error accepting\n”);
add_client(isock, &caddr, &pool);
}
check_clients(&pool);
}
// close it up down here

Your suggestions?

Architecture

A struct something like this:
typedef struct s_pool {
int maxfd;
fd_set read_set;
fd_set write_set;
fd_set ready_set;
int nready;
//
//
//
//
//
int clientfd[FD_SETSIZE];
largest descriptor in sets
all active read descriptors
all active write descriptors
descriptors ready for reading
return of select()
// max index in client array
// might want to write this
read_buf client_read_buf[FD_SETSIZE];
// what else might be helpful for project 1?
} pool;

Basic Commands
 NICK
 USER
 QUIT

Channel Commands
 JOIN
 PART
 LIST

Advanced Commands
 PRIVMSG
 WHO
Client(s)
socket()
Server
socket()
bind()
listen()
connect()
Connection Request
select()
FD_ISSET(sfd)
accept()
write()
read()
read()
Client / Server Session(s)
close()
check_clients() main loop
EOF
write()
read()
close()

Strong I/O skills will be a great assistant.

Read more about this field if interested
 Books as ‘UNIX Network Programming – The Sockets
Networking API’ will be a good tutorial
Deadline:
2011-4-10
Checkpoint: 2011-3-27
Detailed information will be put on the FTP:
 ftp://10.132.141.33/classes/08/102 计算机网络
/PROJECT/project 1



Download