Sockets Tutorial with Python 3 part 1 - sending and receiving data

sentdex
11 Mar 201914:27

Summary

TLDRThis Python tutorial series introduces sockets programming with a focus on creating a server and client using Python's socket library. The video demonstrates setting up a TCP socket, binding it to a local IP and port, and listening for connections. It also covers sending and receiving data between the server and client, and the importance of buffering data streams. The tutorial simplifies the concepts for beginners, highlighting the need for handling larger messages and maintaining open connections in future videos.

Takeaways

  • 📝 The tutorial covers creating a basic server and client using Python's socket library.
  • 🔌 The socket object is created using `socket.socket()` with the AF_INET family for IPv4 and SOCK_STREAM for TCP.
  • 📍 The server binds to a local IP and port, in this case, 'localhost' and port 1234.
  • 🔗 The server listens for incoming connections with a queue of five to handle multiple requests.
  • 🤝 Upon receiving a connection, the server accepts it and stores the client socket and address information.
  • 💬 The server sends a welcome message to the client using UTF-8 encoded bytes.
  • 🔄 The client connects to the server using the same socket object but with the connect method instead of bind.
  • 📡 The client receives messages from the server in chunks, determined by the buffer size set in the receive method.
  • 🔍 The script explains the concept of a socket as an endpoint for sending and receiving data on a network.
  • 🔑 The tutorial touches on the importance of proper buffer management for handling data streams in socket communication.
  • 🔄 The script demonstrates a basic example of socket communication but mentions the need for more complex logic for long-term connections.

Q & A

  • What is the purpose of the 'socket' module in Python?

    -The 'socket' module in Python provides a way to create and manipulate network connections using the BSD socket interface. It is part of Python's standard library and does not require installation.

  • What does 'AF_INET' and 'SOCK_STREAM' represent in the context of creating a socket?

    -'AF_INET' represents the address family, which corresponds to IPv4. 'SOCK_STREAM' represents the type of socket, which in this case is a TCP socket for a streaming connection.

  • Why is the server binding to 'socket.gethostname()' and port 1234?

    -The server is binding to 'socket.gethostname()' to listen on the local machine's hostname and port 1234 to specify the port number on which it will accept incoming connections.

  • What is a socket in networking terms?

    -A socket is an endpoint for sending and receiving data across a network. It sits at an IP address and a port, facilitating communication between networked devices.

  • What does the 'listen' method do for a server socket?

    -The 'listen' method on a server socket allows the server to prepare for incoming connections. It sets up a queue for managing multiple incoming connection requests.

  • How does the server accept a client connection?

    -The server accepts a client connection using the 'accept' method, which returns a new socket object representing the connection, as well as the address of the client.

  • What is the purpose of sending a welcome message to the client socket?

    -Sending a welcome message to the client socket is a way to establish communication and inform the client that the connection has been successfully established.

  • What is the difference between binding a socket and connecting a socket?

    -Binding a socket is done on the server side to specify the IP and port on which it will listen for incoming connections. Connecting a socket is done on the client side to specify the IP and port of the server to which it wants to connect.

  • Why is it necessary to buffer data when using sockets?

    -Buffering data is necessary because sockets deal with a stream of data. The buffer determines how much data is received at a time, which is important for handling varying data sizes and maintaining the flow of data.

  • What is the significance of the 'utf-8' encoding when sending and receiving messages?

    -The 'utf-8' encoding is significant because it allows for the transmission of text data in a standardized format that can be correctly interpreted by both the sender and the receiver.

  • How can you handle receiving messages larger than the buffer size?

    -To handle messages larger than the buffer size, you can implement a loop that continues to receive data until the entire message is buffered. This often involves checking the length of the received message and concatenating the chunks until the complete message is assembled.

  • What is the role of the 'close' method in socket programming?

    -The 'close' method is used to close the socket connection, freeing up the resources associated with the socket. It is important to properly close sockets when they are no longer needed to avoid resource leaks.

Outlines

00:00

🔌 Introduction to Python Sockets

This paragraph introduces the concept of sockets in Python programming. The tutorial begins with the creation of a server and client using Python's built-in 'socket' library, which doesn't require installation. The server is set up to use IPv4 and TCP protocols, binding to the local machine's hostname and port 1234. The explanation includes a brief introduction to what a socket is, highlighting its role as an endpoint for communication. The server is configured to listen for incoming connections with a queue size of five, and upon receiving a connection, it sends a welcome message to the client using UTF-8 encoding. The paragraph concludes with the server printing a debug message indicating a successful connection from the client's address.

05:01

📡 Setting Up the Client Socket

The second paragraph focuses on setting up the client side of the socket communication. It starts by copying the server's socket code and modifying it for the client's purpose. Instead of binding, the client's socket is used to establish a connection to the server's IP and port. The paragraph discusses the flexibility of sockets to connect to local or remote machines, and the importance of choosing an appropriate buffer size for receiving data. It demonstrates receiving a message from the server, decoding it from UTF-8 bytes, and printing it. The client's execution is shown, including running the server and client scripts, and observing the welcome message from the server. The paragraph ends with a brief mention of the need for a more complex and long-term connection strategy in real-world applications.

10:02

🔄 Buffering and Handling Data Streams

The final paragraph delves into the intricacies of buffering data in socket communication. It explains the concept of data streaming and the necessity of handling messages larger than the initial buffer size. The paragraph suggests using a loop to continuously receive data and demonstrates a method to accumulate incoming data into a full message variable. It also touches on the importance of knowing when the connection is completed and how to properly close the client socket. The discussion includes a practical example of modifying the client script to handle a continuous stream of data, and the importance of sending information about the size of the incoming data in the header. The paragraph concludes with a teaser for the next video, which will cover advanced buffering techniques and maintaining an open stream for sockets.

Mindmap

Keywords

💡Socket

A socket is a fundamental concept in network programming, representing one endpoint of a two-way communication link between two programs running on a network. In the video, sockets are used to establish a connection between a server and a client using Python. The script demonstrates creating a socket object, binding it to an IP and port, and then listening for incoming connections, which is central to the video's theme of networking with Python.

💡AF_INET

AF_INET is a constant used in socket programming to specify the address family, which in this case indicates an IPv4 Internet Protocol address. The script mentions 'socket.AF_INET' as part of the socket creation process, which defines the type of network protocol the socket will use, tying it to the Internet's most common addressing system.

💡SOCK_STREAM

SOCK_STREAM is a socket type used for creating a connection-oriented, stream-based socket. In the context of the video, it is used to establish a TCP (Transmission Control Protocol) connection, which ensures data packets are received in the same order they were sent and that the connection is reliable. This is crucial for the server-client model demonstrated in the script.

💡Bind

Binding in socket programming refers to the process of assigning a socket to a specific IP address and port number. In the script, the server socket is bound to 'socket.gethostname()' and a specific port (1234), which allows the server to listen for incoming connections on the local machine, illustrating a key step in setting up a server.

💡Listen

The listen method in socket programming is used to put a socket into a passive mode where it waits for incoming connections. The script describes using 's.listen()' on the server socket to prepare it to accept connections, which is a necessary step before the server can accept any client requests.

💡Accept

Accept is a method used with listening sockets to accept a connection from a client. In the script, 's.accept()' is called to accept a connection, which returns a new socket object representing the connection with the client and the address of the client, demonstrating the server's interaction with a client.

💡UTF-8

UTF-8 is a character encoding for electronic communication that can represent any character in the Unicode standard, yet is backward compatible with ASCII. In the video, 'utf-8' is used when sending and receiving messages to ensure that the text data is properly encoded and decoded, which is essential for communication between the server and client.

💡Connect

The connect method in socket programming is used to initiate a connection to a specified IP address and port number. In the client script, 's.connect()', is used to establish a connection to the server, which is a fundamental action for the client to start communication with the server.

💡Buffer

A buffer in the context of networking is a temporary storage area, usually in memory, where data is held while being transferred between different parts of a system. The script discusses buffering data received from the server, which is important for handling data streams and ensuring that all data is received correctly.

💡Stream

A stream in networking refers to a continuous flow of data between a sender and a receiver, without the need to send and receive messages in discrete packages. The video script explains that the socket established is a 'streaming socket', which means it handles data as a continuous flow, an important concept for understanding how data is sent and received in the example.

💡TCP

TCP, or Transmission Control Protocol, is one of the main protocols in the Internet protocol suite. It is a connection-oriented protocol that guarantees the delivery of data packets in the same order they were sent. The script mentions TCP in the context of using 'SOCK_STREAM', which corresponds to TCP, emphasizing the reliable nature of the connections being made.

Highlights

Introduction to a Python tutorial series on working with sockets.

Explanation of creating server and client .py files for socket communication.

Importing the socket library, which is part of Python's standard libraries.

Creating a socket object with the family type AF_INET and socket type SOCK_STREAM for TCP.

Binding the socket to a tuple consisting of an IP address and a port number.

Understanding the concept of a socket as an endpoint for data communication.

Server preparation for incoming connections with the 'listen' method and a queue size of five.

Accepting client connections and storing the client socket object.

Sending a welcome message to the client using UTF-8 bytes.

Client-side socket connection to the server using the 'connect' method.

Receiving and decoding messages from the server in the client script.

Demonstration of running the server and client scripts and establishing a connection.

Discussion on the immediate disconnection issue and the need for a more persistent connection.

Explanation of buffering data in sockets and handling messages larger than the buffer size.

Technique for continuously receiving data by using a while loop and checking message length.

Clarification on the need to close the client socket to properly end the connection.

Preview of the next tutorial focusing on advanced buffering and maintaining an open stream.

Acknowledgment of channel members and support from the community.

Transcripts

play00:00

what is going on everybody and welcome

play00:02

to a sockets with Python tutorial series

play00:06

in this video we're gonna be working

play00:08

with sockets so we've got a lot of stuff

play00:10

to cover so let's get into it so I've

play00:12

got a server dot pi and a client dot pi

play00:15

already created so if you haven't done

play00:17

that we should probably haven't go ahead

play00:19

and make two files and we're gonna get

play00:21

started in the server dot pi so to get

play00:25

started we're going to import socket now

play00:28

socket is part of your standard

play00:29

libraries so you won't need to install

play00:31

that or anything like that you already

play00:33

have it now what we want to do is define

play00:36

our socket object so s equals socket dot

play00:40

socket and the socket family type is AF

play00:45

eye net and then the actual type of

play00:48

socket is going to be socket dot sock

play00:51

stream now a fi net corresponds to ipv4

play00:55

and sock stream corresponds to TCP so

play01:00

this will be a streaming socket and if

play01:02

anybody knows what a fi net like why is

play01:05

it called a fi net like why don't we

play01:06

just say socket dot I don't know ipv4

play01:09

let me know down below really curious so

play01:12

anyways it is what it is so that's our

play01:15

socket object now what we want to do is

play01:17

bind to that socket so that's dot bind

play01:19

and we want to bind it to a tuple based

play01:22

on sometimes this will be different but

play01:24

anyway the tuple will be in this case

play01:26

because of the type of socket an IP and

play01:28

a ports now this is our server so we're

play01:32

actually just gonna host the server on

play01:34

the same machine that we have the code

play01:35

so we're gonna bind to socket get

play01:37

hostname so whatever the host name is

play01:39

basically localhost and then the port

play01:42

we're gonna go with one two three four

play01:45

you can go with any pretty much

play01:47

four-digit port the lower digits are

play01:49

generally gonna be already occupied by

play01:52

some other program and you just want to

play01:53

step on their toes and more likely

play01:55

they're gonna step on your toes so once

play01:59

we've bound that socket also let's just

play02:02

talk real briefly what even is a socket

play02:04

so so a socket is just the endpoint

play02:08

generally you're gonna have like two

play02:10

endpoints right to have a communication

play02:11

so that's just the end

play02:13

that receives data so with a socket you

play02:16

send in you receive data so the socket

play02:19

itself is not the communication it's

play02:21

just the end point that like receives

play02:23

that communication on that end point

play02:24

sits at an IP and a port so we will s

play02:27

top bind that socket now what we want to

play02:30

do is s dot listen this is our server

play02:33

we're gonna be making some connections

play02:34

to this server so server has to be

play02:35

prepared for these incoming connections

play02:37

and this server will prepare and leave a

play02:40

queue of five so if it's under some sort

play02:43

of heavy load and like multiple

play02:44

connections are coming in so fast that

play02:46

it can't respond quickly enough and they

play02:48

start stacking up we'll have a queue of

play02:49

five should be more than enough for our

play02:52

purposes so then what we're gonna say is

play02:54

now we're just gonna listen basically

play02:56

forever for our connections and if we

play02:58

get one we're gonna say client socket

play03:00

and then address equals s dot except so

play03:04

anybody connects hey we're happy to see

play03:07

you we're gonna connect and then we're

play03:09

going to store the client socket object

play03:11

on into this variable client socket and

play03:13

then address is where are they coming

play03:15

from so this will be like the IP address

play03:17

basically so so what we can accept this

play03:21

and then the client socket this is just

play03:23

another socket object much like our this

play03:25

socket object here we can send

play03:28

information to this socket we can this

play03:30

socket will receive information as we

play03:32

will eventually describe in client pie

play03:34

okay cool so once we've got that

play03:37

connection let's just print some general

play03:39

debugging F strings we're gonna say

play03:43

connection from address has been

play03:49

established exclamation mark because

play03:53

this is serious business okay so now

play03:56

we're gonna do is a client socket dot

play03:59

send so we're actually going to send

play04:03

information to the client socket which I

play04:06

feel like is weird like the client

play04:07

socket is a socket object but it's like

play04:09

a foreign socket object so we're going

play04:11

to send information to it but I almost

play04:15

feel like I don't know it would make

play04:16

more sense to me if like we did s dot

play04:18

send and then we passed in client socket

play04:21

this feels weird to me but anyways this

play04:23

is like our local version of the client

play04:25

socket so to send them for me

play04:27

into that client we're gonna say client

play04:28

socket dot send what do we want to send

play04:31

to this person so we're gonna say bytes

play04:33

you also could just do like a string and

play04:35

then dot in code or whatever anyways

play04:38

we're gonna say here welcome to the

play04:40

server and then what type of bytes are

play04:44

these these are UTF bytes utf-8 bytes so

play04:47

now that's pretty much all we need to do

play04:51

to send some information so I'll save

play04:53

that now this is not nearly enough for

play04:56

regular use but this is a basic examples

play04:58

basic as I could make it so now we're

play05:00

going to work on our client dot pi

play05:03

so again client is much like server it's

play05:05

gonna use the same exact socket so I'm

play05:07

actually going to copy paste that

play05:10

information now this socket rather than

play05:13

binding instead what this socket really

play05:16

wants to do is connect so we're gonna

play05:18

say s dot connect and then we pass a

play05:21

tuple again of the IP and the port that

play05:23

we wish to connect to in this case if

play05:25

its socket get hostname and the IP same

play05:29

as for one two three four now often is

play05:31

the case your client will be like remote

play05:34

to your server it won't actually be on

play05:36

the same machine so with sockets you can

play05:39

communicate to and from Python programs

play05:42

on the same machine on like a locally

play05:45

networked set of machines or even

play05:47

remotely networked machines so it just

play05:50

doesn't matter in most cases you're

play05:52

probably not actually gonna use socket

play05:53

doc yet hostname or at least not all of

play05:55

the cases you will probably won't do

play05:57

that you'll connect to an actual public

play05:59

IP or something like that or a local IP

play06:02

but for now we're gonna do everything on

play06:04

the same machine so everybody can follow

play06:06

along cool so we make our connection and

play06:12

we could be done but what we're gonna

play06:15

accept that message that was sent to us

play06:17

so we're gonna say message equals s dot

play06:20

R ec v4 receive and we're gonna receive

play06:24

and this is our buffer so remember this

play06:27

TCP socket here this is a stream of data

play06:30

so you've got a stream you have to

play06:32

decide in how big of chump chunk chunks

play06:37

or how many chumps uh how big a chunks

play06:40

of data do we want to receive at a time

play06:43

so in this case 1024

play06:45

that's more than Pig enough but it

play06:47

really depends on what you're doing like

play06:48

if you're sending massive files you

play06:50

wouldn't want a really tiny buffer size

play06:52

you might want something a little larger

play06:53

so and then it also depends on the

play06:55

application that you're then gonna use

play06:57

it with and stuff that this case can get

play06:59

really complicated really fast like if

play07:01

you're really into like networking and

play07:02

stuff you could be paid a decent amount

play07:05

of money like to come up with the proper

play07:07

amounts for these things but anyway for

play07:09

now 1024 good enough so now we're gonna

play07:11

say is just print message decode and

play07:17

this was utf-8 so we go to code and

play07:20

again the the the way sockets are

play07:22

communicating at the moment at least

play07:24

with the type of socket that we've

play07:25

established here is a byte stream so

play07:28

we're receiving these bytes so they're

play07:30

sent as bytes the received as bytes and

play07:32

then we just decode the bytes so in this

play07:34

case we should get the message saved

play07:36

everything so now all we need to do is

play07:38

run it so I'm gonna do CMD here and I

play07:42

honestly this is my local machine this

play07:44

is probably not 3/7 yes so instead what

play07:46

I'm gonna say is PI - 3 7 it shouldn't

play07:48

actually matter you should probably be

play07:50

able to do it on any version of Pi 3

play07:51

anyway

play07:52

run the server so the server is now

play07:54

running and now I just need to open up

play07:56

one more for our client PI - 3 point

play08:02

hello 3.7 client dot PI and I think what

play08:07

I'll do is I'll like I don't know

play08:09

something like that we connect we see

play08:12

welcome to the server from our server

play08:15

and then here

play08:17

or can we see it here connection from

play08:19

our IP address has been established okay

play08:22

so it looks like that worked for us but

play08:26

this is also just like immediately

play08:27

disconnected which is probably not

play08:28

really what we're after you're probably

play08:30

looking for a more long-term connection

play08:33

but we could just like keep running that

play08:35

again like every time we wanted to

play08:37

receive a bit of information but that's

play08:39

kind of silly most people aren't

play08:40

actually doing that with sockets they're

play08:42

gonna be doing something far more

play08:43

complex so I think the last thing I want

play08:46

to show you guys before we leave and go

play08:50

to like the next video is you know the

play08:53

way that truly sockets are gonna work in

play08:55

the way that you know you're actually

play08:57

gonna be buffering data is most of the

play08:59

time you you just like can't expect that

play09:01

with this that this will be enough so in

play09:05

this case you could send just about any

play09:07

message as long as it was less than 1024

play09:09

bytes of data and you would be totally

play09:11

fine and you could you could set this as

play09:14

big as you could plausibly conceive but

play09:17

that would be silly what really happens

play09:19

is again it's a stream so I'm gonna set

play09:21

this to 8 and then hit save for the

play09:25

client and I honestly don't remember did

play09:27

we I don't ya know we haven't done

play09:29

anything to the server so I'll leave the

play09:31

server running and instead let's rerun

play09:33

the client again and you'll see what we

play09:35

get is just welcome right because we

play09:40

only received that one little itty-bitty

play09:41

buffer but we're not actually handling

play09:44

for really anything here so so actually

play09:47

what we want to do is while true so Wow

play09:51

true we receive this data so I'll tab

play09:56

that over hit save come back up here

play09:58

rerun it and we get this welcome to this

play10:02

server right ok so yeah that's what

play10:06

happens when you buffer data but why do

play10:09

we have to buffer it I mean like because

play10:10

we could have gotten away with 1024 but

play10:12

eventually someone's gonna try to send a

play10:14

message that's bigger than that and

play10:16

maybe on your chat lesea make a chat app

play10:18

maybe you're care you set a character

play10:20

limit and it becomes more challenging to

play10:22

do more than that but there's almost

play10:25

always going to be a reason why it's

play10:27

gonna be better to buffer also I mean in

play10:29

most cases you're gonna be like

play10:30

below let's say certainly below like 10

play10:33

megabyte buffer so if we're talking like

play10:35

files and stuff you just you have to be

play10:37

able to understand how that's gonna work

play10:39

so then you start thinking well that's

play10:41

not that hard man all we got to do is

play10:45

something like this like I don't know

play10:46

full underscore message and then you

play10:48

just make that an empty string and then

play10:50

here

play10:52

you'll just say maybe something like

play10:54

this like if if or actually what we'll

play11:00

do is under here you would say you know

play11:02

if message is less than or equal to 0

play11:05

right or lend message rather so if

play11:08

length of the message is less than or

play11:11

equal to 0 we're gonna break otherwise

play11:15

what we want to do is full message plus

play11:20

equals MSG dot decode utf-8 who needs

play11:27

Centex right like duh so then after this

play11:31

we could print full message full massage

play11:36

and then we come over here we'll break

play11:38

this one maybe wow I just okay

play11:44

yet jerk pie puh puh - 3.7 client dot

play11:53

pie we try to connect nothing happens

play11:57

but okay so what's going on here well

play12:01

the problem is we still have this

play12:03

connection from the server and the we'd

play12:06

we don't actually know when the

play12:07

connection is fully completed right

play12:09

we're still actually the stream and the

play12:11

connection is still exists so then you

play12:13

come over here maybe and then I don't

play12:15

know client socket closed I think is the

play12:18

proper handling for that unfortunately I

play12:21

don't think I can cancel this from

play12:22

running either it's really annoying why

play12:25

can't I break sockets in running PI -

play12:28

3:7 server dot pi please don't tell me

play12:31

that is a goose come over here rerun

play12:35

client dot pi and then we see welcome to

play12:37

the server and exits and so in this case

play12:40

we were actually able to buffer all of

play12:43

the data

play12:44

and we didn't really need any fancy

play12:45

logic we receive the message and we

play12:48

buffered so what's the big idea well the

play12:51

big idea is it's meant to be a stream

play12:54

we're supposed to be accepting data and

play12:55

a big stream and if server gets

play12:58

something and it decides it wants to

play12:59

send some information we're just simply

play13:01

not going to receive it now we could

play13:03

kind of treat this like a restful api or

play13:05

something and like build data until the

play13:07

client reconnects accepts the buffer and

play13:09

then clears out with the client god or

play13:11

something like that but that's not the

play13:14

way that we typically will work with

play13:16

sockets instead you're going to likely

play13:17

send a bit of information in a header

play13:20

and inform the client how much

play13:22

information is to come so that's we're

play13:24

going to be focusing focusing on in the

play13:26

next video if you got questions comments

play13:29

concerns whatever feel free to leave

play13:32

those below quick shout out to my most

play13:35

recent channel there we go couldn't

play13:38

click on it channel members omni crux

play13:42

miguel lutz lautaro alexander and mary

play13:47

python I love your last name thank you

play13:51

guys very much for your support it

play13:52

allows me to keep doing what I love to

play13:54

do so thank you guys so much and thank

play13:57

you to everybody else eventually I'm

play13:59

gonna figure out a decent way to rethink

play14:02

people who have stuck around some people

play14:03

are still with me for like well over six

play14:06

months I forget exactly what we're at

play14:07

right now for the max but that's

play14:09

freaking awesome so anyways I'll figure

play14:12

out a way at some points so anyways in

play14:15

the next tutorial we'll talk about how

play14:16

do you actually will buffer and keep the

play14:18

stream open and all that and do some

play14:20

more cool stuff with sockets otherwise

play14:23

I'll see you guys in another video

Rate This

5.0 / 5 (0 votes)

Related Tags
Python SocketsServer-ClientNetworkingTCP/IPProgrammingTutorialIPv4Data StreamsBufferingCommunication